From 94d34344bff84fca353c2494d70f7bbf72e6f762 Mon Sep 17 00:00:00 2001 From: ds58 <30220598+ds58@users.noreply.github.com> Date: Wed, 27 Apr 2022 21:36:12 -0500 Subject: [PATCH 01/75] Fix building on MacOS --- CMakeLists.txt | 3 +++ tools/buildtools/download_from_google_storage.py | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9f7cc449..32c508b0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -205,6 +205,9 @@ set(JAVA_FATAL_ERROR "A Java installation is required. Set the JAVA_HOME " "installation directory.") # Find the Java Native Interface (JNI) installation. +set(JAVA_INCLUDE_PATH NotNeeded) +set(JAVA_INCLUDE_PATH2 NotNeeded) +set(JAVA_AWT_INCLUDE_PATH NotNeeded) find_package(JNI ${JDK_MIN_VERSION}) if(NOT ${JNI_FOUND}) message(FATAL_ERROR ${JAVA_FATAL_ERROR}) diff --git a/tools/buildtools/download_from_google_storage.py b/tools/buildtools/download_from_google_storage.py index 3f279545..d409b1ba 100644 --- a/tools/buildtools/download_from_google_storage.py +++ b/tools/buildtools/download_from_google_storage.py @@ -78,7 +78,7 @@ class Gsutil(object): RETRY_BASE_DELAY = 5.0 RETRY_DELAY_MULTIPLE = 1.3 - def __init__(self, path, boto_path=None, version='4.46'): + def __init__(self, path, boto_path=None, version='5.9'): if not os.path.exists(path): raise FileNotFoundError('GSUtil not found in %s' % path) self.path = path From 246e81f400d5d25e87b8b165a30e72a6480b83a7 Mon Sep 17 00:00:00 2001 From: ds58 <30220598+ds58@users.noreply.github.com> Date: Wed, 27 Apr 2022 21:40:38 -0500 Subject: [PATCH 02/75] Add CEF framework path and bundle path to settings (MacOS fix) --- native/context.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/native/context.cpp b/native/context.cpp index 7f894ad9..b47a3956 100644 --- a/native/context.cpp +++ b/native/context.cpp @@ -101,6 +101,16 @@ CefSettings GetJNISettings(JNIEnv* env, jobject obj) { CefString(&settings.locales_dir_path) = tmp; tmp.clear(); } + if (GetJNIFieldString(env, cls, obj, "framework_dir_path", &tmp) && + !tmp.empty()) { + CefString(&settings.framework_dir_path) = tmp; + tmp.clear(); + } + if (GetJNIFieldString(env, cls, obj, "main_bundle_path", &tmp) && + !tmp.empty()) { + CefString(&settings.main_bundle_path) = tmp; + tmp.clear(); + } GetJNIFieldBoolean(env, cls, obj, "pack_loading_disabled", &settings.pack_loading_disabled); GetJNIFieldInt(env, cls, obj, "remote_debugging_port", From 314529cb1f995d1945037a007f86be47bb2602bc Mon Sep 17 00:00:00 2001 From: ds58 <30220598+ds58@users.noreply.github.com> Date: Fri, 17 Jun 2022 12:21:12 -0500 Subject: [PATCH 03/75] Update CMakeLists.txt --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 32c508b0..40750d90 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -130,7 +130,7 @@ set_property(GLOBAL PROPERTY OS_FOLDERS ON) # Specify the CEF distribution version. if(NOT DEFINED CEF_VERSION) - set(CEF_VERSION "100.0.14+g4e5ba66+chromium-100.0.4896.75") + set(CEF_VERSION "100.0.24+g0783cf8+chromium-100.0.4896.127") endif() # Determine the platform. From 0d29b2396d1573a5c9d52c9474cfec9cef5efee9 Mon Sep 17 00:00:00 2001 From: ds58 <30220598+ds58@users.noreply.github.com> Date: Sat, 21 Jan 2023 13:57:13 -0600 Subject: [PATCH 04/75] Add IntelliJ IDEA files to gitignore --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index e7bc7d07..1b266d2e 100644 --- a/.gitignore +++ b/.gitignore @@ -55,3 +55,5 @@ Thumbs.db /tools/buildtools/linux64/clang-format /tools/buildtools/mac/clang-format /tools/buildtools/win/clang-format.exe +.idea +*.iml From 91dfd48765c14d04aa0c204a4fc9755ee129080b Mon Sep 17 00:00:00 2001 From: ds58 <30220598+ds58@users.noreply.github.com> Date: Sat, 21 Jan 2023 13:57:50 -0600 Subject: [PATCH 05/75] Change visibility of CefBrowserOsr and CefBrowser_N --- java/org/cef/browser/CefBrowserOsr.java | 2 +- java/org/cef/browser/CefBrowser_N.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/java/org/cef/browser/CefBrowserOsr.java b/java/org/cef/browser/CefBrowserOsr.java index f0672f9b..1ea57525 100644 --- a/java/org/cef/browser/CefBrowserOsr.java +++ b/java/org/cef/browser/CefBrowserOsr.java @@ -72,7 +72,7 @@ * The visibility of this class is "package". To create a new * CefBrowser instance, please use CefBrowserFactory. */ -class CefBrowserOsr extends CefBrowser_N implements CefRenderHandler { +public class CefBrowserOsr extends CefBrowser_N implements CefRenderHandler { private CefRenderer renderer_; private GLCanvas canvas_; private long window_handle_ = 0; diff --git a/java/org/cef/browser/CefBrowser_N.java b/java/org/cef/browser/CefBrowser_N.java index 406d0256..cebcaa75 100644 --- a/java/org/cef/browser/CefBrowser_N.java +++ b/java/org/cef/browser/CefBrowser_N.java @@ -37,7 +37,7 @@ * The visibility of this class is "package". To create a new * CefBrowser instance, please use CefBrowserFactory. */ -abstract class CefBrowser_N extends CefNativeAdapter implements CefBrowser { +public abstract class CefBrowser_N extends CefNativeAdapter implements CefBrowser { private volatile boolean isPending_ = false; private final CefClient client_; private final String url_; From 6074b4ccb981be3b69319016db7a0f74dac05623 Mon Sep 17 00:00:00 2001 From: ds58 <30220598+ds58@users.noreply.github.com> Date: Sat, 21 Jan 2023 17:02:25 -0600 Subject: [PATCH 06/75] Remove JOGL references, change native library loading system, add macOS settings --- java/org/cef/CefApp.java | 151 +++--- java/org/cef/CefSettings.java | 6 + java/org/cef/browser/CefBrowserOsr.java | 470 +----------------- java/org/cef/browser/CefRenderer.java | 186 +------ .../cef/browser/mac/CefBrowserWindowMac.java | 33 +- 5 files changed, 75 insertions(+), 771 deletions(-) diff --git a/java/org/cef/CefApp.java b/java/org/cef/CefApp.java index afd10f04..a084fee1 100644 --- a/java/org/cef/CefApp.java +++ b/java/org/cef/CefApp.java @@ -140,37 +140,13 @@ public enum CefAppState { private CefApp(String[] args, CefSettings settings) throws UnsatisfiedLinkError { super(args); if (settings != null) settings_ = settings.clone(); - if (OS.isWindows()) { - SystemBootstrap.loadLibrary("jawt"); - SystemBootstrap.loadLibrary("chrome_elf"); - SystemBootstrap.loadLibrary("libcef"); - // Other platforms load this library in CefApp.startup(). - SystemBootstrap.loadLibrary("jcef"); - } else if (OS.isLinux()) { - SystemBootstrap.loadLibrary("cef"); - } if (appHandler_ == null) { appHandler_ = this; } - // Execute on the AWT event dispatching thread. - try { - Runnable r = new Runnable() { - @Override - public void run() { - // Perform native pre-initialization. - if (!N_PreInitialize()) - throw new IllegalStateException("Failed to pre-initialize native code"); - } - }; - if (SwingUtilities.isEventDispatchThread()) - r.run(); - else - SwingUtilities.invokeAndWait(r); - } catch (Exception e) { - e.printStackTrace(); - } + if (!N_PreInitialize()) + throw new IllegalStateException("Failed to pre-initialize native code"); } /** @@ -381,59 +357,34 @@ protected final synchronized void clientWasDisposed(CefClient client) { * @return true on success. */ private final void initialize() { - // Execute on the AWT event dispatching thread. - try { - Runnable r = new Runnable() { - @Override - public void run() { - String library_path = getJcefLibPath(); - System.out.println("initialize on " + Thread.currentThread() - + " with library path " + library_path); - - CefSettings settings = settings_ != null ? settings_ : new CefSettings(); - - // Avoid to override user values by testing on NULL - if (OS.isMacintosh()) { - if (settings.browser_subprocess_path == null) { - Path path = Paths.get(library_path, - "../Frameworks/jcef Helper.app/Contents/MacOS/jcef Helper"); - settings.browser_subprocess_path = - path.normalize().toAbsolutePath().toString(); - } - } else if (OS.isWindows()) { - if (settings.browser_subprocess_path == null) { - Path path = Paths.get(library_path, "jcef_helper.exe"); - settings.browser_subprocess_path = - path.normalize().toAbsolutePath().toString(); - } - } else if (OS.isLinux()) { - if (settings.browser_subprocess_path == null) { - Path path = Paths.get(library_path, "jcef_helper"); - settings.browser_subprocess_path = - path.normalize().toAbsolutePath().toString(); - } - if (settings.resources_dir_path == null) { - Path path = Paths.get(library_path); - settings.resources_dir_path = - path.normalize().toAbsolutePath().toString(); - } - if (settings.locales_dir_path == null) { - Path path = Paths.get(library_path, "locales"); - settings.locales_dir_path = - path.normalize().toAbsolutePath().toString(); - } - } + String jcefPath = getJcefLibPath(); + System.out.println("initialize on " + Thread.currentThread() + " with library path " + jcefPath); - if (N_Initialize(appHandler_, settings)) setState(CefAppState.INITIALIZED); - } - }; - if (SwingUtilities.isEventDispatchThread()) - r.run(); - else - SwingUtilities.invokeAndWait(r); - } catch (Exception e) { - e.printStackTrace(); + CefSettings settings = settings_ != null ? settings_ : new CefSettings(); + + if (OS.isWindows()) { + Path jcefHelperPath = Paths.get(jcefPath, "jcef_helper.exe"); + settings.browser_subprocess_path = jcefHelperPath.normalize().toAbsolutePath().toString(); + } else if (OS.isMacintosh()) { + String basePath = Paths.get(jcefPath).getParent().getParent().toString(); + settings.main_bundle_path = basePath; + settings.framework_dir_path = basePath + + "/Contents/Frameworks/Chromium Embedded Framework.framework"; + settings.locales_dir_path = basePath + + "/Contents/Frameworks/Chromium Embedded Framework.framework/Resources"; + settings.resources_dir_path = basePath + + "/Contents/Frameworks/Chromium Embedded Framework.framework/Resources"; + settings.browser_subprocess_path = basePath + + "/Contents/Frameworks/jcef Helper.app/Contents/MacOS/jcef Helper"; + } else if (OS.isLinux()) { + settings.resources_dir_path = jcefPath; + Path jcefHelperPath = Paths.get(jcefPath, "jcef_helper"); + settings.browser_subprocess_path = jcefHelperPath.normalize().toAbsolutePath().toString(); + Path localesPath = Paths.get(jcefPath, "locales"); + settings.locales_dir_path = localesPath.normalize().toAbsolutePath().toString(); } + + if (N_Initialize(appHandler_, settings)) setState(CefAppState.INITIALIZED); } /** @@ -532,11 +483,26 @@ public void actionPerformed(ActionEvent evt) { * @return True on successful startup. */ public static final boolean startup(String[] args) { - if (OS.isLinux() || OS.isMacintosh()) { - SystemBootstrap.loadLibrary("jcef"); - return N_Startup(OS.isMacintosh() ? getCefFrameworkPath(args) : null); + String jcefPath = getJcefLibPath(); + + if (OS.isWindows()) { + System.load(jcefPath + "/d3dcompiler_47.dll"); + System.load(jcefPath + "/libGLESv2.dll"); + System.load(jcefPath + "/libEGL.dll"); + System.load(jcefPath + "/chrome_elf.dll"); + System.load(jcefPath + "/libcef.dll"); + System.load(jcefPath + "/jcef.dll"); + return true; + } else if (OS.isMacintosh()) { + System.load(jcefPath + "/libjcef.dylib"); + return N_Startup(getCefFrameworkPath(args)); + } else if (OS.isLinux()) { + System.load(jcefPath + "/libcef.so"); + System.load(jcefPath + "/libjcef.so"); + return N_Startup(null); } - return true; + + return false; } /** @@ -544,21 +510,16 @@ public static final boolean startup(String[] args) { * @return The path to the jcef library */ private static final String getJcefLibPath() { - String library_path = System.getProperty("java.library.path"); - String[] paths = library_path.split(System.getProperty("path.separator")); - for (String path : paths) { - File dir = new File(path); - String[] found = dir.list(new FilenameFilter() { - @Override - public boolean accept(File dir, String name) { - return (name.equalsIgnoreCase("libjcef.dylib") - || name.equalsIgnoreCase("libjcef.so") - || name.equalsIgnoreCase("jcef.dll")); - } - }); - if (found != null && found.length != 0) return path; + Path librariesPath = Paths.get(System.getProperty("jcef.path")); + Path jcefPath; + + if (OS.isMacintosh()) { + jcefPath = librariesPath.resolve("jcef_app.app/Contents/Java"); + } else { + jcefPath = librariesPath; } - return library_path; + + return jcefPath.toAbsolutePath().toString(); } /** diff --git a/java/org/cef/CefSettings.java b/java/org/cef/CefSettings.java index 5d756d99..a094b355 100644 --- a/java/org/cef/CefSettings.java +++ b/java/org/cef/CefSettings.java @@ -75,6 +75,10 @@ public ColorType clone() { } } + // macOS specific settings + public String framework_dir_path = null; + public String main_bundle_path = null; + /** * The path to a separate executable that will be launched for sub-processes. * By default the browser process executable is used. See the comments on @@ -235,6 +239,8 @@ public CefSettings() {} @Override public CefSettings clone() { CefSettings tmp = new CefSettings(); + tmp.framework_dir_path = framework_dir_path; + tmp.main_bundle_path = main_bundle_path; tmp.browser_subprocess_path = browser_subprocess_path; tmp.windowless_rendering_enabled = windowless_rendering_enabled; tmp.command_line_args_disabled = command_line_args_disabled; diff --git a/java/org/cef/browser/CefBrowserOsr.java b/java/org/cef/browser/CefBrowserOsr.java index 1ea57525..e057134b 100644 --- a/java/org/cef/browser/CefBrowserOsr.java +++ b/java/org/cef/browser/CefBrowserOsr.java @@ -4,68 +4,18 @@ package org.cef.browser; -import com.jogamp.nativewindow.NativeSurface; -import com.jogamp.opengl.GL; -import com.jogamp.opengl.GL2; -import com.jogamp.opengl.GLAutoDrawable; -import com.jogamp.opengl.GLCapabilities; -import com.jogamp.opengl.GLContext; -import com.jogamp.opengl.GLEventListener; -import com.jogamp.opengl.GLProfile; -import com.jogamp.opengl.awt.GLCanvas; -import com.jogamp.opengl.util.GLBuffers; - import org.cef.CefClient; -import org.cef.OS; import org.cef.callback.CefDragData; import org.cef.handler.CefRenderHandler; import org.cef.handler.CefScreenInfo; -import java.awt.Component; -import java.awt.Cursor; -import java.awt.Graphics; -import java.awt.Graphics2D; -import java.awt.GraphicsConfiguration; -import java.awt.Point; -import java.awt.Rectangle; -import java.awt.datatransfer.StringSelection; -import java.awt.dnd.DnDConstants; -import java.awt.dnd.DragGestureEvent; +import java.awt.*; import java.awt.dnd.DragGestureRecognizer; import java.awt.dnd.DragSource; -import java.awt.dnd.DragSourceAdapter; -import java.awt.dnd.DragSourceDropEvent; -import java.awt.dnd.DropTarget; -import java.awt.event.FocusEvent; -import java.awt.event.FocusListener; -import java.awt.event.KeyEvent; -import java.awt.event.KeyListener; import java.awt.event.MouseEvent; -import java.awt.event.MouseListener; -import java.awt.event.MouseMotionListener; -import java.awt.event.MouseWheelEvent; -import java.awt.event.MouseWheelListener; -import java.awt.geom.AffineTransform; -import java.awt.image.AffineTransformOp; import java.awt.image.BufferedImage; -import java.lang.ClassNotFoundException; -import java.lang.IllegalAccessException; -import java.lang.IllegalArgumentException; -import java.lang.NoSuchMethodException; -import java.lang.SecurityException; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; import java.nio.ByteBuffer; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.concurrent.Callable; import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; - -import javax.swing.MenuSelectionManager; -import javax.swing.SwingUtilities; /** * This class represents an off-screen rendered browser. @@ -74,7 +24,6 @@ */ public class CefBrowserOsr extends CefBrowser_N implements CefRenderHandler { private CefRenderer renderer_; - private GLCanvas canvas_; private long window_handle_ = 0; private boolean justCreated_ = false; private Rectangle browser_rect_ = new Rectangle(0, 0, 1, 1); // Work around CEF issue #1437. @@ -93,7 +42,6 @@ private CefBrowserOsr(CefClient client, String url, boolean transparent, super(client, url, context, parent, inspectAt); isTransparent_ = transparent; renderer_ = new CefRenderer(transparent); - createGLCanvas(); } @Override @@ -105,7 +53,7 @@ public void createImmediately() { @Override public Component getUIComponent() { - return canvas_; + return null; } @Override @@ -120,215 +68,6 @@ protected CefBrowser_N createDevToolsBrowser(CefClient client, String url, client, url, isTransparent_, context, (CefBrowserOsr) this, inspectAt); } - private synchronized long getWindowHandle() { - if (window_handle_ == 0) { - NativeSurface surface = canvas_.getNativeSurface(); - if (surface != null) { - surface.lockSurface(); - window_handle_ = getWindowHandle(surface.getSurfaceHandle()); - surface.unlockSurface(); - assert (window_handle_ != 0); - } - } - return window_handle_; - } - - @SuppressWarnings("serial") - private void createGLCanvas() { - GLProfile glprofile = GLProfile.getMaxFixedFunc(true); - GLCapabilities glcapabilities = new GLCapabilities(glprofile); - canvas_ = new GLCanvas(glcapabilities) { - private Method scaleFactorAccessor = null; - private boolean removed_ = true; - - @Override - public void paint(Graphics g) { - createBrowserIfRequired(true); - if (g instanceof Graphics2D) { - GraphicsConfiguration config = ((Graphics2D) g).getDeviceConfiguration(); - depth = config.getColorModel().getPixelSize(); - depth_per_component = config.getColorModel().getComponentSize()[0]; - - if (OS.isMacintosh() - && System.getProperty("java.runtime.version").startsWith("1.8")) { - // This fixes a weird thing on MacOS: the scale factor being read from - // getTransform().getScaleX() is incorrect for Java 8 VMs; it is always - // 1, even though Retina display scaling of window sizes etc. is - // definitely ongoing somewhere in the lower levels of AWT. This isn't - // too big of a problem for us, because the transparent scaling handles - // the situation, except for one thing: the screenshot-grabbing - // code below, which reads from the OpenGL context, must know the real - // scale factor, because the image to be read is larger by that factor - // and thus a bigger buffer is required. This is why there's some - // admittedly-ugly reflection magic going on below that's able to get - // the real scale factor. - // All of this is not relevant for either Windows or MacOS JDKs > 8, - // for which the official "getScaleX()" approach works fine. - try { - if (scaleFactorAccessor == null) { - scaleFactorAccessor = getClass() - .getClassLoader() - .loadClass("sun.awt.CGraphicsDevice") - .getDeclaredMethod("getScaleFactor"); - } - Object factor = scaleFactorAccessor.invoke(config.getDevice()); - if (factor instanceof Integer) { - scaleFactor_ = ((Integer) factor).doubleValue(); - } else { - scaleFactor_ = 1.0; - } - } catch (InvocationTargetException | IllegalAccessException - | IllegalArgumentException | NoSuchMethodException - | SecurityException | ClassNotFoundException exc) { - scaleFactor_ = 1.0; - } - } else { - scaleFactor_ = ((Graphics2D) g).getTransform().getScaleX(); - } - } - super.paint(g); - } - - @Override - public void addNotify() { - super.addNotify(); - if (removed_) { - notifyAfterParentChanged(); - removed_ = false; - } - } - - @Override - public void removeNotify() { - if (!removed_) { - if (!isClosed()) { - notifyAfterParentChanged(); - } - removed_ = true; - } - super.removeNotify(); - } - }; - - // The GLContext will be re-initialized when changing displays, resulting in calls to - // dispose/init/reshape. - canvas_.addGLEventListener(new GLEventListener() { - @Override - public void reshape( - GLAutoDrawable glautodrawable, int x, int y, int width, int height) { - int newWidth = width; - int newHeight = height; - if (OS.isMacintosh()) { - // HiDPI display scale correction support code - // For some reason this does seem to be necessary on MacOS only. - // If doing this correction on Windows, the browser content would be too - // small and in the lower left corner of the canvas only. - newWidth = (int) (width / scaleFactor_); - newHeight = (int) (height / scaleFactor_); - } - browser_rect_.setBounds(x, y, newWidth, newHeight); - screenPoint_ = canvas_.getLocationOnScreen(); - wasResized(newWidth, newHeight); - } - - @Override - public void init(GLAutoDrawable glautodrawable) { - renderer_.initialize(glautodrawable.getGL().getGL2()); - } - - @Override - public void dispose(GLAutoDrawable glautodrawable) { - renderer_.cleanup(glautodrawable.getGL().getGL2()); - } - - @Override - public void display(GLAutoDrawable glautodrawable) { - renderer_.render(glautodrawable.getGL().getGL2()); - } - }); - - canvas_.addMouseListener(new MouseListener() { - @Override - public void mousePressed(MouseEvent e) { - sendMouseEvent(e); - } - - @Override - public void mouseReleased(MouseEvent e) { - sendMouseEvent(e); - } - - @Override - public void mouseEntered(MouseEvent e) { - sendMouseEvent(e); - } - - @Override - public void mouseExited(MouseEvent e) { - sendMouseEvent(e); - } - - @Override - public void mouseClicked(MouseEvent e) { - sendMouseEvent(e); - } - }); - - canvas_.addMouseMotionListener(new MouseMotionListener() { - @Override - public void mouseMoved(MouseEvent e) { - sendMouseEvent(e); - } - - @Override - public void mouseDragged(MouseEvent e) { - sendMouseEvent(e); - } - }); - - canvas_.addMouseWheelListener(new MouseWheelListener() { - @Override - public void mouseWheelMoved(MouseWheelEvent e) { - sendMouseWheelEvent(e); - } - }); - - canvas_.addKeyListener(new KeyListener() { - @Override - public void keyTyped(KeyEvent e) { - sendKeyEvent(e); - } - - @Override - public void keyPressed(KeyEvent e) { - sendKeyEvent(e); - } - - @Override - public void keyReleased(KeyEvent e) { - sendKeyEvent(e); - } - }); - - canvas_.setFocusable(true); - canvas_.addFocusListener(new FocusListener() { - @Override - public void focusLost(FocusEvent e) { - setFocus(false); - } - - @Override - public void focusGained(FocusEvent e) { - // Dismiss any Java menus that are currently displayed. - MenuSelectionManager.defaultManager().clearSelectedPath(); - setFocus(true); - } - }); - - // Connect the Canvas with a drag and drop listener. - new DropTarget(canvas_, new CefDropTargetListener(this)); - } - @Override public Rectangle getViewRect(CefBrowser browser) { return browser_rect_; @@ -355,38 +94,11 @@ public void onPopupSize(CefBrowser browser, Rectangle size) { } @Override - public void onPaint(CefBrowser browser, boolean popup, Rectangle[] dirtyRects, - ByteBuffer buffer, int width, int height) { - // if window is closing, canvas_ or opengl context could be null - final GLContext context = canvas_ != null ? canvas_.getContext() : null; - - if (context == null) { - return; - } - - // This result can occur due to GLContext re-initialization when changing displays. - if (context.makeCurrent() == GLContext.CONTEXT_NOT_CURRENT) { - return; - } - - renderer_.onPaint(canvas_.getGL().getGL2(), popup, dirtyRects, buffer, width, height); - context.release(); - SwingUtilities.invokeLater(new Runnable() { - public void run() { - canvas_.display(); - } - }); + public void onPaint(CefBrowser browser, boolean popup, Rectangle[] dirtyRects, ByteBuffer buffer, int width, int height) { } @Override public boolean onCursorChange(CefBrowser browser, final int cursorType) { - SwingUtilities.invokeLater(new Runnable() { - public void run() { - canvas_.setCursor(new Cursor(cursorType)); - } - }); - - // OSR always handles the cursor change. return true; } @@ -403,23 +115,6 @@ protected void unregisterListeners() {} @Override public boolean startDragging(CefBrowser browser, CefDragData dragData, int mask, int x, int y) { - int action = (mask & CefDragData.DragOperations.DRAG_OPERATION_MOVE) == 0 - ? DnDConstants.ACTION_COPY - : DnDConstants.ACTION_MOVE; - MouseEvent triggerEvent = - new MouseEvent(canvas_, MouseEvent.MOUSE_DRAGGED, 0, 0, x, y, 0, false); - DragGestureEvent ev = new DragGestureEvent( - new SyntheticDragGestureRecognizer(canvas_, action, triggerEvent), action, - new Point(x, y), new ArrayList<>(Arrays.asList(triggerEvent))); - - DragSource.getDefaultDragSource().startDrag(ev, /*dragCursor=*/null, - new StringSelection(dragData.getFragmentText()), new DragSourceAdapter() { - @Override - public void dragDropEnd(DragSourceDropEvent dsde) { - dragSourceEndedAt(dsde.getLocation(), mask); - dragSourceSystemDragEnded(); - } - }); return true; } @@ -431,10 +126,6 @@ public void updateDragCursor(CefBrowser browser, int operation) { private void createBrowserIfRequired(boolean hasParent) { long windowHandle = 0; - if (hasParent) { - windowHandle = getWindowHandle(); - } - if (getNativeRef("CefBrowser") == 0) { if (getParentBrowser() != null) { createDevTools(getParentBrowser(), getClient(), windowHandle, true, isTransparent_, @@ -466,159 +157,6 @@ public boolean getScreenInfo(CefBrowser browser, CefScreenInfo screenInfo) { @Override public CompletableFuture createScreenshot(boolean nativeResolution) { - int width = (int) Math.ceil(canvas_.getWidth() * scaleFactor_); - int height = (int) Math.ceil(canvas_.getHeight() * scaleFactor_); - - // In order to grab a screenshot of the browser window, we need to get the OpenGL internals - // from the GLCanvas that displays the browser. - GL2 gl = canvas_.getGL().getGL2(); - int textureId = renderer_.getTextureID(); - - // This mirrors the two ways in which CefRenderer may render images internally - either via - // an incrementally updated texture that is the same size as the window and simply rendered - // onto a textured quad by graphics hardware, in which case we capture the data directly - // from this texture, or by directly writing pixels into the OpenGL framebuffer, in which - // case we directly read those pixels back. The latter is the way chosen if there is no - // hardware rasterizer capability detected. We can simply distinguish both approaches by - // looking whether the textureId of the renderer is a valid (non-zero) one. - boolean useReadPixels = (textureId == 0); - - // This Callable encapsulates the pixel-reading code. After running it, the screenshot - // BufferedImage contains the grabbed image. - final Callable pixelGrabberCallable = new Callable() { - @Override - public BufferedImage call() { - BufferedImage screenshot = - new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); - ByteBuffer buffer = GLBuffers.newDirectByteBuffer(width * height * 4); - - gl.getContext().makeCurrent(); - try { - if (useReadPixels) { - // If pixels are copied directly to the framebuffer, we also directly read - // them back. - gl.glReadPixels( - 0, 0, width, height, GL.GL_RGBA, GL.GL_UNSIGNED_BYTE, buffer); - } else { - // In this case, read the texture pixel data from the previously-retrieved - // texture ID - gl.glEnable(GL.GL_TEXTURE_2D); - gl.glBindTexture(GL.GL_TEXTURE_2D, textureId); - gl.glGetTexImage( - GL.GL_TEXTURE_2D, 0, GL.GL_RGBA, GL.GL_UNSIGNED_BYTE, buffer); - gl.glDisable(GL.GL_TEXTURE_2D); - } - } finally { - gl.getContext().release(); - } - - for (int y = 0; y < height; y++) { - for (int x = 0; x < width; x++) { - // The OpenGL functions only support RGBA, while Java BufferedImage uses - // ARGB. We must convert. - int r = (buffer.get() & 0xff); - int g = (buffer.get() & 0xff); - int b = (buffer.get() & 0xff); - int a = (buffer.get() & 0xff); - int argb = (a << 24) | (r << 16) | (g << 8) | (b << 0); - // If pixels were read from the framebuffer, we have to flip the resulting - // image on the Y axis, as the OpenGL framebuffer's y axis starts at the - // bottom of the image pointing "upwards", while BufferedImage has the - // origin in the upper left corner. This flipping is done when drawing into - // the BufferedImage. - screenshot.setRGB(x, useReadPixels ? (height - y - 1) : y, argb); - } - } - - if (!nativeResolution && scaleFactor_ != 1.0) { - // HiDPI images should be resized down to "normal" levels - BufferedImage resized = - new BufferedImage((int) (screenshot.getWidth() / scaleFactor_), - (int) (screenshot.getHeight() / scaleFactor_), - BufferedImage.TYPE_INT_ARGB); - AffineTransform tempTransform = new AffineTransform(); - tempTransform.scale(1.0 / scaleFactor_, 1.0 / scaleFactor_); - AffineTransformOp tempScaleOperation = - new AffineTransformOp(tempTransform, AffineTransformOp.TYPE_BILINEAR); - resized = tempScaleOperation.filter(screenshot, resized); - return resized; - } else { - return screenshot; - } - } - }; - - if (SwingUtilities.isEventDispatchThread()) { - // If called on the AWT event thread, just access the GL API - try { - BufferedImage screenshot = pixelGrabberCallable.call(); - return CompletableFuture.completedFuture(screenshot); - } catch (Exception e) { - CompletableFuture future = new CompletableFuture(); - future.completeExceptionally(e); - return future; - } - } else { - // If called from another thread, register a GLEventListener and trigger an async - // redraw, during which we use the GL API to grab the pixel data. An unresolved Future - // is returned, on which the caller can wait for a result (but not with the Event - // Thread, as we need that for pixel grabbing, which is why there's a safeguard in place - // to catch that situation if it accidentally happens). - CompletableFuture future = new CompletableFuture() { - private void safeguardGet() { - if (SwingUtilities.isEventDispatchThread()) { - throw new RuntimeException( - "Waiting on this Future using the AWT Event Thread is illegal, " - + "because it can potentially deadlock the thread."); - } - } - - @Override - public BufferedImage get() throws InterruptedException, ExecutionException { - safeguardGet(); - return super.get(); - } - - @Override - public BufferedImage get(long timeout, TimeUnit unit) - throws InterruptedException, ExecutionException, TimeoutException { - safeguardGet(); - return super.get(timeout, unit); - } - }; - canvas_.addGLEventListener(new GLEventListener() { - @Override - public void reshape( - GLAutoDrawable aDrawable, int aArg1, int aArg2, int aArg3, int aArg4) { - // ignore - } - - @Override - public void init(GLAutoDrawable aDrawable) { - // ignore - } - - @Override - public void dispose(GLAutoDrawable aDrawable) { - // ignore - } - - @Override - public void display(GLAutoDrawable aDrawable) { - canvas_.removeGLEventListener(this); - try { - future.complete(pixelGrabberCallable.call()); - } catch (Exception e) { - future.completeExceptionally(e); - } - } - }); - - // This repaint triggers an indirect call to the listeners' display method above, which - // ultimately completes the future that we return immediately. - canvas_.repaint(); - - return future; - } + return null; } } diff --git a/java/org/cef/browser/CefRenderer.java b/java/org/cef/browser/CefRenderer.java index 2a295465..aabe01d9 100644 --- a/java/org/cef/browser/CefRenderer.java +++ b/java/org/cef/browser/CefRenderer.java @@ -4,15 +4,12 @@ package org.cef.browser; -import com.jogamp.opengl.GL2; - -import java.awt.Rectangle; +import java.awt.*; import java.nio.ByteBuffer; -import java.nio.FloatBuffer; -class CefRenderer { +public class CefRenderer { private boolean transparent_; - private GL2 initialized_context_ = null; +// private GL2 initialized_context_ = null; private int[] texture_id_ = new int[1]; private int view_width_ = 0; private int view_height_ = 0; @@ -35,103 +32,14 @@ protected int getTextureID() { } @SuppressWarnings("static-access") - protected void initialize(GL2 gl2) { - if (initialized_context_ == gl2) return; - - initialized_context_ = gl2; - - if (!gl2.getContext().isHardwareRasterizer()) { - // Workaround for Windows Remote Desktop which requires pot textures. - System.out.println( - "opengl rendering may be slow as hardware rendering isn't available"); - use_draw_pixels_ = true; - return; - } - - gl2.glHint(gl2.GL_POLYGON_SMOOTH_HINT, gl2.GL_NICEST); - - gl2.glClearColor(0.0f, 0.0f, 0.0f, 1.0f); + protected void initialize() { - // Necessary for non-power-of-2 textures to render correctly. - gl2.glPixelStorei(gl2.GL_UNPACK_ALIGNMENT, 1); - - // Create the texture. - gl2.glGenTextures(1, texture_id_, 0); - assert (texture_id_[0] != 0); - - gl2.glBindTexture(gl2.GL_TEXTURE_2D, texture_id_[0]); - gl2.glTexParameteri(gl2.GL_TEXTURE_2D, gl2.GL_TEXTURE_MIN_FILTER, gl2.GL_NEAREST); - gl2.glTexParameteri(gl2.GL_TEXTURE_2D, gl2.GL_TEXTURE_MAG_FILTER, gl2.GL_NEAREST); - gl2.glTexEnvf(gl2.GL_TEXTURE_ENV, gl2.GL_TEXTURE_ENV_MODE, gl2.GL_MODULATE); } - protected void cleanup(GL2 gl2) { - if (texture_id_[0] != 0) gl2.glDeleteTextures(1, texture_id_, 0); - view_width_ = view_height_ = 0; + protected void cleanup() { } - @SuppressWarnings("static-access") - protected void render(GL2 gl2) { - if (use_draw_pixels_ || view_width_ == 0 || view_height_ == 0) return; - - assert (initialized_context_ != null); - - final float[] vertex_data = {// tu, tv, x, y, z - 0.0f, 1.0f, -1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f, -1.0f, 0.0f, 1.0f, 0.0f, 1.0f, - 1.0f, 0.0f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f}; - FloatBuffer vertices = FloatBuffer.wrap(vertex_data); - - gl2.glClear(gl2.GL_COLOR_BUFFER_BIT | gl2.GL_DEPTH_BUFFER_BIT); - - gl2.glMatrixMode(gl2.GL_MODELVIEW); - gl2.glLoadIdentity(); - - // Match GL units to screen coordinates. - gl2.glViewport(0, 0, view_width_, view_height_); - gl2.glMatrixMode(gl2.GL_PROJECTION); - gl2.glLoadIdentity(); - - // Draw the background gradient. - gl2.glPushAttrib(gl2.GL_ALL_ATTRIB_BITS); - gl2.glBegin(gl2.GL_QUADS); - gl2.glColor4f(1.0f, 0.0f, 0.0f, 1.0f); // red - gl2.glVertex2f(-1.0f, -1.0f); - gl2.glVertex2f(1.0f, -1.0f); - gl2.glColor4f(0.0f, 0.0f, 1.0f, 1.0f); // blue - gl2.glVertex2f(1.0f, 1.0f); - gl2.glVertex2f(-1.0f, 1.0f); - gl2.glEnd(); - gl2.glPopAttrib(); - - // Rotate the view based on the mouse spin. - if (spin_x_ != 0) gl2.glRotatef(-spin_x_, 1.0f, 0.0f, 0.0f); - if (spin_y_ != 0) gl2.glRotatef(-spin_y_, 0.0f, 1.0f, 0.0f); - - if (transparent_) { - // Alpha blending style. Texture values have premultiplied alpha. - gl2.glBlendFunc(gl2.GL_ONE, gl2.GL_ONE_MINUS_SRC_ALPHA); - - // Enable alpha blending. - gl2.glEnable(gl2.GL_BLEND); - } - - // Enable 2D textures. - gl2.glEnable(gl2.GL_TEXTURE_2D); - - // Draw the facets with the texture. - assert (texture_id_[0] != 0); - gl2.glColor4f(1.0f, 1.0f, 1.0f, 1.0f); - gl2.glBindTexture(gl2.GL_TEXTURE_2D, texture_id_[0]); - gl2.glInterleavedArrays(gl2.GL_T2F_V3F, 0, vertices); - gl2.glDrawArrays(gl2.GL_QUADS, 0, 4); - - // Disable 2D textures. - gl2.glDisable(gl2.GL_TEXTURE_2D); - - if (transparent_) { - // Disable alpha blending. - gl2.glDisable(gl2.GL_BLEND); - } + protected void render() { } protected void onPopupSize(Rectangle rect) { @@ -163,87 +71,7 @@ protected void clearPopupRects() { original_popup_rect_.setBounds(0, 0, 0, 0); } - @SuppressWarnings("static-access") - protected void onPaint(GL2 gl2, boolean popup, Rectangle[] dirtyRects, ByteBuffer buffer, - int width, int height) { - initialize(gl2); - - if (use_draw_pixels_) { - gl2.glRasterPos2f(-1, 1); - gl2.glPixelZoom(1, -1); - gl2.glDrawPixels(width, height, GL2.GL_BGRA, GL2.GL_UNSIGNED_BYTE, buffer); - return; - } - - if (transparent_) { - // Enable alpha blending. - gl2.glEnable(gl2.GL_BLEND); - } - - // Enable 2D textures. - gl2.glEnable(gl2.GL_TEXTURE_2D); - - assert (texture_id_[0] != 0); - gl2.glBindTexture(gl2.GL_TEXTURE_2D, texture_id_[0]); - - if (!popup) { - int old_width = view_width_; - int old_height = view_height_; - - view_width_ = width; - view_height_ = height; - - gl2.glPixelStorei(gl2.GL_UNPACK_ROW_LENGTH, view_width_); - - if (old_width != view_width_ || old_height != view_height_) { - // Update/resize the whole texture. - gl2.glPixelStorei(gl2.GL_UNPACK_SKIP_PIXELS, 0); - gl2.glPixelStorei(gl2.GL_UNPACK_SKIP_ROWS, 0); - gl2.glTexImage2D(gl2.GL_TEXTURE_2D, 0, gl2.GL_RGBA, view_width_, view_height_, 0, - gl2.GL_BGRA, gl2.GL_UNSIGNED_INT_8_8_8_8_REV, buffer); - } else { - // Update just the dirty rectangles. - for (int i = 0; i < dirtyRects.length; ++i) { - Rectangle rect = dirtyRects[i]; - gl2.glPixelStorei(gl2.GL_UNPACK_SKIP_PIXELS, rect.x); - gl2.glPixelStorei(gl2.GL_UNPACK_SKIP_ROWS, rect.y); - gl2.glTexSubImage2D(gl2.GL_TEXTURE_2D, 0, rect.x, rect.y, rect.width, - rect.height, gl2.GL_BGRA, gl2.GL_UNSIGNED_INT_8_8_8_8_REV, buffer); - } - } - } else if (popup && popup_rect_.width > 0 && popup_rect_.height > 0) { - int skip_pixels = 0, x = popup_rect_.x; - int skip_rows = 0, y = popup_rect_.y; - int w = width; - int h = height; - - // Adjust the popup to fit inside the view. - if (x < 0) { - skip_pixels = -x; - x = 0; - } - if (y < 0) { - skip_rows = -y; - y = 0; - } - if (x + w > view_width_) w -= x + w - view_width_; - if (y + h > view_height_) h -= y + h - view_height_; - - // Update the popup rectangle. - gl2.glPixelStorei(gl2.GL_UNPACK_ROW_LENGTH, width); - gl2.glPixelStorei(gl2.GL_UNPACK_SKIP_PIXELS, skip_pixels); - gl2.glPixelStorei(gl2.GL_UNPACK_SKIP_ROWS, skip_rows); - gl2.glTexSubImage2D(gl2.GL_TEXTURE_2D, 0, x, y, w, h, gl2.GL_BGRA, - gl2.GL_UNSIGNED_INT_8_8_8_8_REV, buffer); - } - - // Disable 2D textures. - gl2.glDisable(gl2.GL_TEXTURE_2D); - - if (transparent_) { - // Disable alpha blending. - gl2.glDisable(gl2.GL_BLEND); - } + protected void onPaint(boolean popup, Rectangle[] dirtyRects, ByteBuffer buffer, int width, int height) { } protected void setSpin(float spinX, float spinY) { diff --git a/java/org/cef/browser/mac/CefBrowserWindowMac.java b/java/org/cef/browser/mac/CefBrowserWindowMac.java index 3239edce..15cccff9 100644 --- a/java/org/cef/browser/mac/CefBrowserWindowMac.java +++ b/java/org/cef/browser/mac/CefBrowserWindowMac.java @@ -6,40 +6,11 @@ import org.cef.browser.CefBrowserWindow; -import java.awt.Component; -import java.awt.peer.ComponentPeer; - -import sun.awt.AWTAccessor; -import sun.lwawt.LWComponentPeer; -import sun.lwawt.PlatformWindow; -import sun.lwawt.macosx.CFRetainedResource; -import sun.lwawt.macosx.CPlatformWindow; +import java.awt.*; public class CefBrowserWindowMac implements CefBrowserWindow { @Override public long getWindowHandle(Component comp) { - final long[] result = new long[1]; - while (comp != null) { - if (comp.isLightweight()) { - comp = comp.getParent(); - continue; - } - ComponentPeer peer = AWTAccessor.getComponentAccessor().getPeer(comp); - if (peer instanceof LWComponentPeer) { - @SuppressWarnings("rawtypes") - PlatformWindow pWindow = ((LWComponentPeer) peer).getPlatformWindow(); - if (pWindow instanceof CPlatformWindow) { - ((CPlatformWindow) pWindow).execute(new CFRetainedResource.CFNativeAction() { - @Override - public void run(long l) { - result[0] = l; - } - }); - break; - } - } - comp = comp.getParent(); - } - return result[0]; + return 0; } } From 8ae856472c3c273dce084cd9486571d651ba9a55 Mon Sep 17 00:00:00 2001 From: ds58 <30220598+ds58@users.noreply.github.com> Date: Sat, 21 Jan 2023 17:24:41 -0600 Subject: [PATCH 07/75] Remove various implementation of CefRenderer from CefBrowserOsr --- java/org/cef/CefApp.java | 2 +- java/org/cef/browser/CefBrowserOsr.java | 20 ++++---------------- java/org/cef/browser/CefRenderer.java | 2 +- 3 files changed, 6 insertions(+), 18 deletions(-) diff --git a/java/org/cef/CefApp.java b/java/org/cef/CefApp.java index a084fee1..7e2be595 100644 --- a/java/org/cef/CefApp.java +++ b/java/org/cef/CefApp.java @@ -544,7 +544,7 @@ private static final String getCefFrameworkPath(String[] args) { private final native boolean N_PreInitialize(); private final native boolean N_Initialize(CefAppHandler appHandler, CefSettings settings); private final native void N_Shutdown(); - private final native void N_DoMessageLoopWork(); + public final native void N_DoMessageLoopWork(); private final native CefVersion N_GetVersion(); private final native boolean N_RegisterSchemeHandlerFactory( String schemeName, String domainName, CefSchemeHandlerFactory factory); diff --git a/java/org/cef/browser/CefBrowserOsr.java b/java/org/cef/browser/CefBrowserOsr.java index e057134b..c5d2a766 100644 --- a/java/org/cef/browser/CefBrowserOsr.java +++ b/java/org/cef/browser/CefBrowserOsr.java @@ -23,17 +23,15 @@ * CefBrowser instance, please use CefBrowserFactory. */ public class CefBrowserOsr extends CefBrowser_N implements CefRenderHandler { - private CefRenderer renderer_; - private long window_handle_ = 0; private boolean justCreated_ = false; - private Rectangle browser_rect_ = new Rectangle(0, 0, 1, 1); // Work around CEF issue #1437. + protected Rectangle browser_rect_ = new Rectangle(0, 0, 1, 1); // Work around CEF issue #1437. private Point screenPoint_ = new Point(0, 0); private double scaleFactor_ = 1.0; private int depth = 32; private int depth_per_component = 8; private boolean isTransparent_; - CefBrowserOsr(CefClient client, String url, boolean transparent, CefRequestContext context) { + public CefBrowserOsr(CefClient client, String url, boolean transparent, CefRequestContext context) { this(client, url, transparent, context, null, null); } @@ -41,7 +39,6 @@ private CefBrowserOsr(CefClient client, String url, boolean transparent, CefRequestContext context, CefBrowserOsr parent, Point inspectAt) { super(client, url, context, parent, inspectAt); isTransparent_ = transparent; - renderer_ = new CefRenderer(transparent); } @Override @@ -62,10 +59,8 @@ public CefRenderHandler getRenderHandler() { } @Override - protected CefBrowser_N createDevToolsBrowser(CefClient client, String url, - CefRequestContext context, CefBrowser_N parent, Point inspectAt) { - return new CefBrowserOsr( - client, url, isTransparent_, context, (CefBrowserOsr) this, inspectAt); + protected CefBrowser_N createDevToolsBrowser(CefClient client, String url, CefRequestContext context, CefBrowser_N parent, Point inspectAt) { + return null; } @Override @@ -82,15 +77,10 @@ public Point getScreenPoint(CefBrowser browser, Point viewPoint) { @Override public void onPopupShow(CefBrowser browser, boolean show) { - if (!show) { - renderer_.clearPopupRects(); - invalidate(); - } } @Override public void onPopupSize(CefBrowser browser, Rectangle size) { - renderer_.onPopupSize(size); } @Override @@ -120,8 +110,6 @@ public boolean startDragging(CefBrowser browser, CefDragData dragData, int mask, @Override public void updateDragCursor(CefBrowser browser, int operation) { - // TODO: Consider calling onCursorChange() if we want different cursors based on - // |operation|. } private void createBrowserIfRequired(boolean hasParent) { diff --git a/java/org/cef/browser/CefRenderer.java b/java/org/cef/browser/CefRenderer.java index aabe01d9..bc7cd153 100644 --- a/java/org/cef/browser/CefRenderer.java +++ b/java/org/cef/browser/CefRenderer.java @@ -27,7 +27,7 @@ protected boolean isTransparent() { return transparent_; } - protected int getTextureID() { + public int getTextureID() { return texture_id_[0]; } From 93aea8d74454a44febc6296e2739931351cf5872 Mon Sep 17 00:00:00 2001 From: ds58 <30220598+ds58@users.noreply.github.com> Date: Sun, 22 Jan 2023 13:41:19 -0600 Subject: [PATCH 08/75] Delete doMessageLoopWork implementation, delete CefRenderer --- java/org/cef/CefApp.java | 44 +------------- java/org/cef/browser/CefRenderer.java | 86 --------------------------- 2 files changed, 1 insertion(+), 129 deletions(-) delete mode 100644 java/org/cef/browser/CefRenderer.java diff --git a/java/org/cef/CefApp.java b/java/org/cef/CefApp.java index 7e2be595..9469205a 100644 --- a/java/org/cef/CefApp.java +++ b/java/org/cef/CefApp.java @@ -430,49 +430,7 @@ public void run() { * Windows with windowed rendering. */ public final void doMessageLoopWork(final long delay_ms) { - // Execute on the AWT event dispatching thread. - SwingUtilities.invokeLater(new Runnable() { - @Override - public void run() { - if (getState() == CefAppState.TERMINATED) return; - - // The maximum number of milliseconds we're willing to wait between - // calls to DoMessageLoopWork(). - final long kMaxTimerDelay = 1000 / 30; // 30fps - - if (workTimer_ != null) { - workTimer_.stop(); - workTimer_ = null; - } - - if (delay_ms <= 0) { - // Execute the work immediately. - N_DoMessageLoopWork(); - - // Schedule more work later. - doMessageLoopWork(kMaxTimerDelay); - } else { - long timer_delay_ms = delay_ms; - // Never wait longer than the maximum allowed time. - if (timer_delay_ms > kMaxTimerDelay) timer_delay_ms = kMaxTimerDelay; - - workTimer_ = new Timer((int) timer_delay_ms, new ActionListener() { - @Override - public void actionPerformed(ActionEvent evt) { - // Timer has timed out. - workTimer_.stop(); - workTimer_ = null; - - N_DoMessageLoopWork(); - - // Schedule more work later. - doMessageLoopWork(kMaxTimerDelay); - } - }); - workTimer_.start(); - } - } - }); + // Do nothing, handled by custom game tick loop } /** diff --git a/java/org/cef/browser/CefRenderer.java b/java/org/cef/browser/CefRenderer.java deleted file mode 100644 index bc7cd153..00000000 --- a/java/org/cef/browser/CefRenderer.java +++ /dev/null @@ -1,86 +0,0 @@ -// Copyright (c) 2013 The Chromium Embedded Framework Authors. All rights -// reserved. Use of this source code is governed by a BSD-style license that -// can be found in the LICENSE file. - -package org.cef.browser; - -import java.awt.*; -import java.nio.ByteBuffer; - -public class CefRenderer { - private boolean transparent_; -// private GL2 initialized_context_ = null; - private int[] texture_id_ = new int[1]; - private int view_width_ = 0; - private int view_height_ = 0; - private float spin_x_ = 0f; - private float spin_y_ = 0f; - private Rectangle popup_rect_ = new Rectangle(0, 0, 0, 0); - private Rectangle original_popup_rect_ = new Rectangle(0, 0, 0, 0); - private boolean use_draw_pixels_ = false; - - protected CefRenderer(boolean transparent) { - transparent_ = transparent; - } - - protected boolean isTransparent() { - return transparent_; - } - - public int getTextureID() { - return texture_id_[0]; - } - - @SuppressWarnings("static-access") - protected void initialize() { - - } - - protected void cleanup() { - } - - protected void render() { - } - - protected void onPopupSize(Rectangle rect) { - if (rect.width <= 0 || rect.height <= 0) return; - original_popup_rect_ = rect; - popup_rect_ = getPopupRectInWebView(original_popup_rect_); - } - - protected Rectangle getPopupRect() { - return (Rectangle) popup_rect_.clone(); - } - - protected Rectangle getPopupRectInWebView(Rectangle original_rect) { - Rectangle rc = original_rect; - // if x or y are negative, move them to 0. - if (rc.x < 0) rc.x = 0; - if (rc.y < 0) rc.y = 0; - // if popup goes outside the view, try to reposition origin - if (rc.x + rc.width > view_width_) rc.x = view_width_ - rc.width; - if (rc.y + rc.height > view_height_) rc.y = view_height_ - rc.height; - // if x or y became negative, move them to 0 again. - if (rc.x < 0) rc.x = 0; - if (rc.y < 0) rc.y = 0; - return rc; - } - - protected void clearPopupRects() { - popup_rect_.setBounds(0, 0, 0, 0); - original_popup_rect_.setBounds(0, 0, 0, 0); - } - - protected void onPaint(boolean popup, Rectangle[] dirtyRects, ByteBuffer buffer, int width, int height) { - } - - protected void setSpin(float spinX, float spinY) { - spin_x_ = spinX; - spin_y_ = spinY; - } - - protected void incrementSpin(float spinDX, float spinDY) { - spin_x_ -= spinDX; - spin_y_ -= spinDY; - } -} From 6f9ddcb78228fdaac0eacba04f905a6aa97cff9f Mon Sep 17 00:00:00 2001 From: ds58 <30220598+ds58@users.noreply.github.com> Date: Sun, 22 Jan 2023 18:28:12 -0600 Subject: [PATCH 09/75] Add dummy parent component --- java/org/cef/browser/CefBrowserOsr.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/java/org/cef/browser/CefBrowserOsr.java b/java/org/cef/browser/CefBrowserOsr.java index c5d2a766..224fd119 100644 --- a/java/org/cef/browser/CefBrowserOsr.java +++ b/java/org/cef/browser/CefBrowserOsr.java @@ -31,6 +31,13 @@ public class CefBrowserOsr extends CefBrowser_N implements CefRenderHandler { private int depth_per_component = 8; private boolean isTransparent_; + protected final Component dummyComponent = new Component() { + @Override + public Point getLocationOnScreen() { + return new Point(0, 0); + } + }; + public CefBrowserOsr(CefClient client, String url, boolean transparent, CefRequestContext context) { this(client, url, transparent, context, null, null); } @@ -50,7 +57,7 @@ public void createImmediately() { @Override public Component getUIComponent() { - return null; + return dummyComponent; } @Override From 09d0d85611eae3fabe748a4b99c036309cf59a4b Mon Sep 17 00:00:00 2001 From: ds58 <30220598+ds58@users.noreply.github.com> Date: Sat, 4 Feb 2023 15:10:35 -0600 Subject: [PATCH 10/75] Update README.md --- README.md | 56 ++----------------------------------------------------- 1 file changed, 2 insertions(+), 54 deletions(-) diff --git a/README.md b/README.md index b0f854d4..ef8fa2f2 100644 --- a/README.md +++ b/README.md @@ -1,54 +1,2 @@ -The Java Chromium Embedded Framework (JCEF) is a simple framework for embedding Chromium-based browsers in other applications using the Java programming language. - -# Quick Links - -* Building JCEF - https://bitbucket.org/chromiumembedded/java-cef/wiki/BranchesAndBuilding -* Support Forum - http://magpcss.org/ceforum/viewforum.php?f=17 -* Downloads - https://github.com/jcefmaven/jcefbuild -* Maven/Gradle Artifacts - https://github.com/jcefmaven/jcefmaven -* Donations - http://www.magpcss.org/ceforum/donate.php - -# Introduction - -CEF is a BSD-licensed open source project founded by Marshall Greenblatt in 2008 and based on the [Google Chromium](http://www.chromium.org/Home) project. Unlike the Chromium project itself, which focuses mainly on Google Chrome application development, CEF focuses on facilitating embedded browser use cases in third-party applications. CEF insulates the user from the underlying Chromium and Blink code complexity by offering production-quality stable APIs, release branches tracking specific Chromium releases, and binary distributions. Most features in CEF have default implementations that provide rich functionality while requiring little or no integration work from the user. There are currently over 100 million installed instances of CEF around the world embedded in products from a wide range of companies and industries. A partial list of companies and products using CEF is available on the [CEF Wikipedia page](http://en.wikipedia.org/wiki/Chromium_Embedded_Framework#Applications_using_CEF). Some use cases for CEF include: - -* Embedding an HTML5-compliant Web browser control in an existing native application. -* Creating a light-weight native “shell” application that hosts a user interface developed primarily using Web technologies. -* Rendering Web content “off-screen” in applications that have their own custom drawing frameworks. -* Acting as a host for automated testing of existing Web properties and applications. - -CEF supports a wide range of programming languages and operating systems and can be easily integrated into both new and existing applications. It was designed from the ground up with both performance and ease of use in mind. The base framework includes C and C++ programming interfaces exposed via native libraries that insulate the host application from Chromium and Blink implementation details. It provides close integration between the browser and the host application including support for custom plugins, protocols, JavaScript objects and JavaScript extensions. The host application can optionally control resource loading, navigation, context menus, printing and more, while taking advantage of the same performance and HTML5 technologies available in the Google Chrome Web browser. - -This project provides a Java Wrapper for CEF (JCEF). - -# Building JCEF - -The JCEF project is an extension of the Chromium Embedded Framework (CEF) project hosted at https://bitbucket.org/chromiumembedded/cef/. JCEF maintains a development branch that tracks the most recent CEF3 release branch. JCEF source code can be downloaded, built and packaged into a binary distribution. Once you have created the binary distribution for your platform you can distribute it as a stand-alone package without further dependencies on the JCEF, CEF or Chromium source code. Visit the [BranchesAndBuilding](https://bitbucket.org/chromiumembedded/java-cef/wiki/BranchesAndBuilding) Wiki page for detailed instructions. - -# Helping Out - -JCEF is still very much a work in progress. Some ways that you can help out: - -\- Vote for issues in the [JCEF issue tracker](https://bitbucket.org/chromiumembedded/java-cef/issues?status=new&status=open) that are important to you. This helps with development prioritization. - -\- Report any bugs that you find or feature requests that are important to you. Make sure to first search for existing issues before creating new ones. Please use the [JCEF Forum](http://magpcss.org/ceforum/viewforum.php?f=17) and not the issue tracker for usage questions. Each JCEF issue should: - -* Include the JCEF revision, CEF revision or binary distribution version. -* Include information about your OS and compiler version. -* If the issue is a bug please provide detailed reproduction information. -* If the issue is a feature please describe why the feature is beneficial. - -\- Write unit tests for new or existing functionality. - -\- Pull requests and patches are welcome. View open issues in the [JCEF issue tracker](https://bitbucket.org/chromiumembedded/java-cef/issues?status=new&status=open) or search for TODO(cef) in the source code for ideas. - -If you would like to contribute source code changes to JCEF please follow the below guidelines: - -\- Create or find an appropriate issue for each distinct bug, feature or change. - -\- Submit a [pull request](https://bitbucket.org/chromiumembedded/java-cef/wiki/ContributingWithGit) or create a patch with your changes and attach it to the JCEF issue. Changes should: - -* Be submitted against the current [JCEF master branch](https://bitbucket.org/chromiumembedded/java-cef/src/?at=master) unless explicitly fixing a bug in a CEF release branch. -* Follow the style of existing JCEF source files. In general JCEF uses the [Chromium coding style](http://www.chromium.org/developers/coding-style). -* Include new or modified unit tests as appropriate to the functionality. -* Not include unnecessary or unrelated changes. \ No newline at end of file +# CinemaMod java-cef +Modified version of java-cef for use with CinemaMod From 01c41e74ea274188b05833f95ca3acdd6eec153c Mon Sep 17 00:00:00 2001 From: ds58 <30220598+ds58@users.noreply.github.com> Date: Wed, 8 Feb 2023 19:17:22 -0600 Subject: [PATCH 11/75] Download CEF from cinemamod mirror --- CMakeLists.txt | 7 ++++++- cmake/DownloadCEF.cmake | 4 ++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 40750d90..b5e72b1f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -128,6 +128,11 @@ set_property(GLOBAL PROPERTY OS_FOLDERS ON) # CEF configuration. # +# Specify the CEF branch +if(NOT DEFINED CEF_BRANCH) + set(CEF_BRANCH "4896") +endif() + # Specify the CEF distribution version. if(NOT DEFINED CEF_VERSION) set(CEF_VERSION "100.0.24+g0783cf8+chromium-100.0.4896.127") @@ -159,7 +164,7 @@ set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake") # Download and extract the CEF binary distribution (executes DownloadCEF.cmake). include(DownloadCEF) -DownloadCEF("${CEF_PLATFORM}" "${CEF_VERSION}" "${CMAKE_SOURCE_DIR}/third_party/cef") +DownloadCEF("${CEF_PLATFORM}" "${CEF_BRANCH}" "${CEF_VERSION}" "${CMAKE_SOURCE_DIR}/third_party/cef") # Add the CEF binary distribution's cmake/ directory to the module path. set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CEF_ROOT}/cmake") diff --git a/cmake/DownloadCEF.cmake b/cmake/DownloadCEF.cmake index a64592bc..6db6c8fb 100644 --- a/cmake/DownloadCEF.cmake +++ b/cmake/DownloadCEF.cmake @@ -8,7 +8,7 @@ # Visit https://cef-builds.spotifycdn.com/index.html for the list of # supported platforms and versions. -function(DownloadCEF platform version download_dir) +function(DownloadCEF platform branch version download_dir) # Specify the binary distribution type and download directory. set(CEF_DISTRIBUTION "cef_binary_${version}_${platform}") set(CEF_DOWNLOAD_DIR "${download_dir}") @@ -21,7 +21,7 @@ function(DownloadCEF platform version download_dir) set(CEF_DOWNLOAD_FILENAME "${CEF_DISTRIBUTION}.tar.bz2") set(CEF_DOWNLOAD_PATH "${CEF_DOWNLOAD_DIR}/${CEF_DOWNLOAD_FILENAME}") if(NOT EXISTS "${CEF_DOWNLOAD_PATH}") - set(CEF_DOWNLOAD_URL "https://cef-builds.spotifycdn.com/${CEF_DOWNLOAD_FILENAME}") + set(CEF_DOWNLOAD_URL "https://ewr1.vultrobjects.com/cef-builds/${branch}/${CEF_DOWNLOAD_FILENAME}") string(REPLACE "+" "%2B" CEF_DOWNLOAD_URL_ESCAPED ${CEF_DOWNLOAD_URL}) # Download the SHA1 hash for the binary distribution. From bfaa5de68db200695589aad4ff64147487ce4ee6 Mon Sep 17 00:00:00 2001 From: ds58 <30220598+ds58@users.noreply.github.com> Date: Sat, 11 Feb 2023 17:45:35 -0600 Subject: [PATCH 12/75] Don't check download hashes for now --- .gitignore | 1 + cmake/DownloadCEF.cmake | 8 ++++---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/.gitignore b/.gitignore index 1b266d2e..071b39d8 100644 --- a/.gitignore +++ b/.gitignore @@ -57,3 +57,4 @@ Thumbs.db /tools/buildtools/win/clang-format.exe .idea *.iml +.vscode diff --git a/cmake/DownloadCEF.cmake b/cmake/DownloadCEF.cmake index 6db6c8fb..d7967a19 100644 --- a/cmake/DownloadCEF.cmake +++ b/cmake/DownloadCEF.cmake @@ -25,15 +25,15 @@ function(DownloadCEF platform branch version download_dir) string(REPLACE "+" "%2B" CEF_DOWNLOAD_URL_ESCAPED ${CEF_DOWNLOAD_URL}) # Download the SHA1 hash for the binary distribution. - message(STATUS "Downloading ${CEF_DOWNLOAD_PATH}.sha1 from ${CEF_DOWNLOAD_URL_ESCAPED}...") - file(DOWNLOAD "${CEF_DOWNLOAD_URL_ESCAPED}.sha1" "${CEF_DOWNLOAD_PATH}.sha1") - file(READ "${CEF_DOWNLOAD_PATH}.sha1" CEF_SHA1) + # message(STATUS "Downloading ${CEF_DOWNLOAD_PATH}.sha1 from ${CEF_DOWNLOAD_URL_ESCAPED}...") + # file(DOWNLOAD "${CEF_DOWNLOAD_URL_ESCAPED}.sha1" "${CEF_DOWNLOAD_PATH}.sha1") + # file(READ "${CEF_DOWNLOAD_PATH}.sha1" CEF_SHA1) # Download the binary distribution and verify the hash. message(STATUS "Downloading ${CEF_DOWNLOAD_PATH}...") file( DOWNLOAD "${CEF_DOWNLOAD_URL_ESCAPED}" "${CEF_DOWNLOAD_PATH}" - EXPECTED_HASH SHA1=${CEF_SHA1} + # EXPECTED_HASH SHA1=${CEF_SHA1} SHOW_PROGRESS ) endif() From 5f131499ec0a2268fb149fcbf847b8d05427a6e5 Mon Sep 17 00:00:00 2001 From: ds58 <30220598+ds58@users.noreply.github.com> Date: Sat, 11 Feb 2023 17:52:52 -0600 Subject: [PATCH 13/75] Cmake find JNI --- CMakeLists.txt | 3 --- 1 file changed, 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b5e72b1f..467dda40 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -210,9 +210,6 @@ set(JAVA_FATAL_ERROR "A Java installation is required. Set the JAVA_HOME " "installation directory.") # Find the Java Native Interface (JNI) installation. -set(JAVA_INCLUDE_PATH NotNeeded) -set(JAVA_INCLUDE_PATH2 NotNeeded) -set(JAVA_AWT_INCLUDE_PATH NotNeeded) find_package(JNI ${JDK_MIN_VERSION}) if(NOT ${JNI_FOUND}) message(FATAL_ERROR ${JAVA_FATAL_ERROR}) From 088b1d48b7f29a1a1d4b7536659913c75a0c8290 Mon Sep 17 00:00:00 2001 From: Marshall Greenblatt Date: Mon, 3 Oct 2022 14:46:43 -0400 Subject: [PATCH 14/75] buildtools: Update to depot_tools rev 7bb5c487f --- CMakeLists.txt | 16 +++- tools/buildtools/README.jcef | 5 +- .../download_from_google_storage.py | 86 ++++++++++++------- tools/buildtools/gsutil.py | 72 ++++++++++------ tools/buildtools/linux64/clang-format.sha1 | 2 +- tools/buildtools/mac/clang-format.arm64.sha1 | 1 + tools/buildtools/mac/clang-format.sha1 | 1 - tools/buildtools/mac/clang-format.x64.sha1 | 1 + tools/buildtools/subprocess2.py | 37 +++++--- tools/buildtools/win/clang-format.exe.sha1 | 2 +- tools/fix_style.sh | 2 +- 11 files changed, 150 insertions(+), 75 deletions(-) create mode 100644 tools/buildtools/mac/clang-format.arm64.sha1 delete mode 100644 tools/buildtools/mac/clang-format.sha1 create mode 100644 tools/buildtools/mac/clang-format.x64.sha1 diff --git a/CMakeLists.txt b/CMakeLists.txt index 467dda40..c7be1fce 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -142,7 +142,13 @@ endif() if("${CMAKE_SYSTEM_NAME}" STREQUAL "Darwin") if("${PROJECT_ARCH}" STREQUAL "arm64") set(CEF_PLATFORM "macosarm64") + elseif("${PROJECT_ARCH}" STREQUAL "x86_64") + set(CEF_PLATFORM "macosx64") + elseif("${CMAKE_HOST_SYSTEM_PROCESSOR}" STREQUAL "arm64") + set(PROJECT_ARCH "arm64") + set(CEF_PLATFORM "macosarm64") else() + set(PROJECT_ARCH "x86_64") set(CEF_PLATFORM "macosx64") endif() elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux") @@ -263,12 +269,19 @@ file(COPY "${CEF_ROOT}/README.txt" DESTINATION "${CMAKE_BINARY_DIR}") if(OS_WINDOWS) set(GS_PLATFORM "win32") set(GS_HASHPATH "win/clang-format.exe.sha1") + set(GS_OUTPATH "win/clang-format.exe") elseif(OS_MACOSX) set(GS_PLATFORM "darwin") - set(GS_HASHPATH "mac/clang-format.sha1") + if("${CMAKE_HOST_SYSTEM_PROCESSOR}" STREQUAL "arm64") + set(GS_HASHPATH "mac/clang-format.arm64.sha1") + else() + set(GS_HASHPATH "mac/clang-format.x64.sha1") + endif() + set(GS_OUTPATH "mac/clang-format") elseif(OS_LINUX) set(GS_PLATFORM "linux*") set(GS_HASHPATH "linux64/clang-format.sha1") + set(GS_OUTPATH "linux64/clang-format") endif() message(STATUS "Downloading clang-format from Google Storage...") @@ -280,6 +293,7 @@ execute_process( "--no_auth" "--bucket" "chromium-clang-format" "-s" "tools/buildtools/${GS_HASHPATH}" + "-o" "tools/buildtools/${GS_OUTPATH}" WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} RESULT_VARIABLE EXECUTE_RV ) diff --git a/tools/buildtools/README.jcef b/tools/buildtools/README.jcef index c90189e4..298b17d1 100644 --- a/tools/buildtools/README.jcef +++ b/tools/buildtools/README.jcef @@ -1,8 +1,8 @@ Name: depot_tools Short Name: depot_tools URL: https://chromium.googlesource.com/chromium/tools/depot_tools.git -Date: 11 Jan 2020 -Revision: 7a8bf9489 +Date: 21 Sep 2022 +Revision: 08bb5c487f License: BSD License File: LICENSE @@ -11,4 +11,3 @@ Select tools extracted from depot_tools. Local Modifications: - Remove dependency on vpython. -- Update gsutil version to 4.46. diff --git a/tools/buildtools/download_from_google_storage.py b/tools/buildtools/download_from_google_storage.py index d409b1ba..fb3fb985 100644 --- a/tools/buildtools/download_from_google_storage.py +++ b/tools/buildtools/download_from_google_storage.py @@ -1,8 +1,7 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # Copyright (c) 2012 The Chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. - """Download files from Google Storage based on SHA1 sums.""" from __future__ import print_function @@ -45,9 +44,10 @@ 'aix7': 'aix', } - -class FileNotFoundError(IOError): - pass +if sys.version_info.major == 2: + # pylint: disable=redefined-builtin + class FileNotFoundError(IOError): + pass class InvalidFileError(IOError): @@ -78,12 +78,11 @@ class Gsutil(object): RETRY_BASE_DELAY = 5.0 RETRY_DELAY_MULTIPLE = 1.3 - def __init__(self, path, boto_path=None, version='5.9'): + def __init__(self, path, boto_path=None): if not os.path.exists(path): raise FileNotFoundError('GSUtil not found in %s' % path) self.path = path self.boto_path = boto_path - self.version = version def get_sub_env(self): env = os.environ.copy() @@ -100,12 +99,12 @@ def get_sub_env(self): return env def call(self, *args): - cmd = [sys.executable, self.path, '--force-version', self.version] + cmd = [sys.executable, self.path] cmd.extend(args) return subprocess2.call(cmd, env=self.get_sub_env()) def check_call(self, *args): - cmd = [sys.executable, self.path, '--force-version', self.version] + cmd = [sys.executable, self.path] cmd.extend(args) ((out, err), code) = subprocess2.communicate( cmd, @@ -129,7 +128,7 @@ def check_call(self, *args): def check_call_with_retries(self, *args): delay = self.RETRY_BASE_DELAY - for i in xrange(self.MAX_TRIES): + for i in range(self.MAX_TRIES): code, out, err = self.check_call(*args) if not code or i == self.MAX_TRIES - 1: break @@ -254,40 +253,59 @@ def _downloader_worker_thread(thread_num, q, force, base_url, continue extract_dir = output_filename[:-len('.tar.gz')] if os.path.exists(output_filename) and not force: - if not extract or os.path.exists(extract_dir): - if get_sha1(output_filename) == input_sha1_sum: - continue - # Check if file exists. + skip = get_sha1(output_filename) == input_sha1_sum + if extract: + # Additional condition for extract: + # 1) extract_dir must exist + # 2) .tmp flag file mustn't exist + if not os.path.exists(extract_dir): + out_q.put('%d> Extract dir %s does not exist, re-downloading...' % + (thread_num, extract_dir)) + skip = False + # .tmp file is created just before extraction and removed just after + # extraction. If such file exists, it means the process was terminated + # mid-extraction and therefore needs to be extracted again. + elif os.path.exists(extract_dir + '.tmp'): + out_q.put('%d> Detected tmp flag file for %s, ' + 're-downloading...' % (thread_num, output_filename)) + skip = False + if skip: + continue + file_url = '%s/%s' % (base_url, input_sha1_sum) - (code, _, err) = gsutil.check_call('ls', file_url) + + try: + if delete: + os.remove(output_filename) # Delete the file if it exists already. + except OSError: + if os.path.exists(output_filename): + out_q.put('%d> Warning: deleting %s failed.' % ( + thread_num, output_filename)) + if verbose: + out_q.put('%d> Downloading %s@%s...' % ( + thread_num, output_filename, input_sha1_sum)) + code, _, err = gsutil.check_call('cp', file_url, output_filename) if code != 0: if code == 404: out_q.put('%d> File %s for %s does not exist, skipping.' % ( thread_num, file_url, output_filename)) ret_codes.put((1, 'File %s for %s does not exist.' % ( file_url, output_filename))) + elif code == 401: + out_q.put( + """%d> Failed to fetch file %s for %s due to unauthorized access, + skipping. Try running `gsutil.py config` and pass 0 if you don't + know your project id.""" % (thread_num, file_url, output_filename)) + ret_codes.put( + (1, 'Failed to fetch file %s for %s due to unauthorized access.' % + (file_url, output_filename))) else: # Other error, probably auth related (bad ~/.boto, etc). out_q.put('%d> Failed to fetch file %s for %s, skipping. [Err: %s]' % (thread_num, file_url, output_filename, err)) - ret_codes.put((1, 'Failed to fetch file %s for %s. [Err: %s]' % + ret_codes.put((code, 'Failed to fetch file %s for %s. [Err: %s]' % (file_url, output_filename, err))) continue - # Fetch the file. - if verbose: - out_q.put('%d> Downloading %s...' % (thread_num, output_filename)) - try: - if delete: - os.remove(output_filename) # Delete the file if it exists already. - except OSError: - if os.path.exists(output_filename): - out_q.put('%d> Warning: deleting %s failed.' % ( - thread_num, output_filename)) - code, _, err = gsutil.check_call('cp', file_url, output_filename) - if code != 0: - out_q.put('%d> %s' % (thread_num, err)) - ret_codes.put((code, err)) - continue remote_sha1 = get_sha1(output_filename) if remote_sha1 != input_sha1_sum: @@ -327,7 +345,9 @@ def _downloader_worker_thread(thread_num, q, force, base_url, out_q.put('%d> Extracting %d entries from %s to %s' % (thread_num, len(tar.getmembers()),output_filename, extract_dir)) - tar.extractall(path=dirname) + with open(extract_dir + '.tmp', 'a'): + tar.extractall(path=dirname) + os.remove(extract_dir + '.tmp') # Set executable bit. if sys.platform == 'cygwin': # Under cygwin, mark all files as executable. The executable flag in @@ -373,7 +393,7 @@ def _data_exists(input_sha1_sum, output_filename, extract): input_sha1_sum: Expected sha1 stored on disk. output_filename: The file to potentially download later. Its sha1 will be compared to input_sha1_sum. - extract: Wheather or not a downloaded file should be extracted. If the file + extract: Whether or not a downloaded file should be extracted. If the file is not extracted, this just compares the sha1 of the file. If the file is to be extracted, this only compares the sha1 of the target archive if the target directory already exists. The content of the target directory diff --git a/tools/buildtools/gsutil.py b/tools/buildtools/gsutil.py index 63847d21..cff91fa7 100644 --- a/tools/buildtools/gsutil.py +++ b/tools/buildtools/gsutil.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # Copyright 2014 The Chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. @@ -31,11 +31,11 @@ THIS_DIR = os.path.dirname(os.path.abspath(__file__)) DEFAULT_BIN_DIR = os.path.join(THIS_DIR, 'external_bin', 'gsutil') -DEFAULT_FALLBACK_GSUTIL = os.path.join( - THIS_DIR, 'third_party', 'gsutil', 'gsutil') IS_WINDOWS = os.name == 'nt' +VERSION = '4.68' + class InvalidGsutilError(Exception): pass @@ -79,7 +79,7 @@ def download_gsutil(version, target_dir): @contextlib.contextmanager def temporary_directory(base): - tmpdir = tempfile.mkdtemp(prefix='gsutil_py', dir=base) + tmpdir = tempfile.mkdtemp(prefix='t', dir=base) try: yield tmpdir finally: @@ -98,7 +98,20 @@ def ensure_gsutil(version, target, clean): return gsutil_bin if not os.path.exists(target): - os.makedirs(target) + try: + os.makedirs(target) + except FileExistsError: + # Another process is prepping workspace, so let's check if gsutil_bin is + # present. If after several checks it's still not, continue with + # downloading gsutil. + delay = 2 # base delay, in seconds + for _ in range(3): # make N attempts + # sleep first as it's not expected to have file ready just yet. + time.sleep(delay) + delay *= 1.5 # next delay increased by that factor + if os.path.isfile(gsutil_bin): + return gsutil_bin + with temporary_directory(target) as instance_dir: # Clean up if we're redownloading a corrupted gsutil. cleanup_path = os.path.join(instance_dir, 'clean') @@ -109,16 +122,12 @@ def ensure_gsutil(version, target, clean): if cleanup_path: shutil.rmtree(cleanup_path) - download_dir = os.path.join(instance_dir, 'download') + download_dir = os.path.join(instance_dir, 'd') target_zip_filename = download_gsutil(version, instance_dir) with zipfile.ZipFile(target_zip_filename, 'r') as target_zip: target_zip.extractall(download_dir) - try: - os.rename(download_dir, bin_dir) - except (OSError, IOError): - # Something else did this in parallel. - pass + shutil.move(download_dir, bin_dir) # Final check that the gsutil bin exists. This should never fail. if not os.path.isfile(gsutil_bin): raise InvalidGsutilError() @@ -129,29 +138,45 @@ def ensure_gsutil(version, target, clean): return gsutil_bin -def run_gsutil(force_version, fallback, target, args, clean=False): - if force_version: - gsutil_bin = ensure_gsutil(force_version, target, clean) - else: - gsutil_bin = fallback - disable_update = ['-o', 'GSUtil:software_update_check_period=0'] - cmd = [sys.executable, gsutil_bin] + disable_update + args - return subprocess.call(cmd) +def run_gsutil(target, args, clean=False): + gsutil_bin = ensure_gsutil(VERSION, target, clean) + args_opt = ['-o', 'GSUtil:software_update_check_period=0'] + if sys.platform == 'darwin': + # We are experiencing problems with multiprocessing on MacOS where gsutil.py + # may hang. + # This behavior is documented in gsutil codebase, and recommendation is to + # set GSUtil:parallel_process_count=1. + # https://github.com/GoogleCloudPlatform/gsutil/blob/06efc9dc23719fab4fd5fadb506d252bbd3fe0dd/gslib/command.py#L1331 + # https://github.com/GoogleCloudPlatform/gsutil/issues/1100 + args_opt.extend(['-o', 'GSUtil:parallel_process_count=1']) + assert sys.platform != 'cygwin' + cmd = [ + sys.executable, + gsutil_bin + ] + args_opt + args + return subprocess.call(cmd, shell=IS_WINDOWS) def parse_args(): bin_dir = os.environ.get('DEPOT_TOOLS_GSUTIL_BIN_DIR', DEFAULT_BIN_DIR) - parser = argparse.ArgumentParser() - parser.add_argument('--force-version', default='4.30') + # Help is disabled as it conflicts with gsutil -h, which controls headers. + parser = argparse.ArgumentParser(add_help=False) + parser.add_argument('--clean', action='store_true', help='Clear any existing gsutil package, forcing a new download.') - parser.add_argument('--fallback', default=DEFAULT_FALLBACK_GSUTIL) parser.add_argument('--target', default=bin_dir, help='The target directory to download/store a gsutil version in. ' '(default is %(default)s).') + + # These two args exist for backwards-compatibility but are no-ops. + parser.add_argument('--force-version', default=VERSION, + help='(deprecated, this flag has no effect)') + parser.add_argument('--fallback', + help='(deprecated, this flag has no effect)') + parser.add_argument('args', nargs=argparse.REMAINDER) args, extras = parser.parse_known_args() @@ -164,8 +189,7 @@ def parse_args(): def main(): args = parse_args() - return run_gsutil(args.force_version, args.fallback, args.target, args.args, - clean=args.clean) + return run_gsutil(args.target, args.args, clean=args.clean) if __name__ == '__main__': diff --git a/tools/buildtools/linux64/clang-format.sha1 b/tools/buildtools/linux64/clang-format.sha1 index e2b3199a..6f3349c5 100644 --- a/tools/buildtools/linux64/clang-format.sha1 +++ b/tools/buildtools/linux64/clang-format.sha1 @@ -1 +1 @@ -942fc8b1789144b8071d3fc03ff0fcbe1cf81ac8 \ No newline at end of file +dd736afb28430c9782750fc0fd5f0ed497399263 \ No newline at end of file diff --git a/tools/buildtools/mac/clang-format.arm64.sha1 b/tools/buildtools/mac/clang-format.arm64.sha1 new file mode 100644 index 00000000..46f9b3c1 --- /dev/null +++ b/tools/buildtools/mac/clang-format.arm64.sha1 @@ -0,0 +1 @@ +f1424c44ee758922823d6b37de43705955c99d7e \ No newline at end of file diff --git a/tools/buildtools/mac/clang-format.sha1 b/tools/buildtools/mac/clang-format.sha1 deleted file mode 100644 index d32c6265..00000000 --- a/tools/buildtools/mac/clang-format.sha1 +++ /dev/null @@ -1 +0,0 @@ -025ca7c75f37ef4a40f3a67d81ddd11d7d0cdb9b \ No newline at end of file diff --git a/tools/buildtools/mac/clang-format.x64.sha1 b/tools/buildtools/mac/clang-format.x64.sha1 new file mode 100644 index 00000000..3a23ea22 --- /dev/null +++ b/tools/buildtools/mac/clang-format.x64.sha1 @@ -0,0 +1 @@ +a1b33be85faf2578f3101d7806e443e1c0949498 \ No newline at end of file diff --git a/tools/buildtools/subprocess2.py b/tools/buildtools/subprocess2.py index dea1a2d6..7df49da1 100644 --- a/tools/buildtools/subprocess2.py +++ b/tools/buildtools/subprocess2.py @@ -21,18 +21,18 @@ if sys.version_info.major == 2: import Queue codecs.lookup('string-escape') + # Sends stdout or stderr to os.devnull. + DEVNULL = open(os.devnull, 'r+') else: import queue as Queue # pylint: disable=redefined-builtin basestring = (str, bytes) + DEVNULL = subprocess.DEVNULL # Constants forwarded from subprocess. PIPE = subprocess.PIPE STDOUT = subprocess.STDOUT -# Sends stdout or stderr to os.devnull. -VOID = open(os.devnull, 'w') -VOID_INPUT = open(os.devnull, 'r') class CalledProcessError(subprocess.CalledProcessError): @@ -48,7 +48,11 @@ def __str__(self): ' '.join(self.cmd), self.returncode) if self.cwd: out += ' in ' + self.cwd - return '\n'.join(filter(None, (out, self.stdout, self.stderr))) + if self.stdout: + out += '\n' + self.stdout.decode('utf-8', 'ignore') + if self.stderr: + out += '\n' + self.stderr.decode('utf-8', 'ignore') + return out class CygwinRebaseError(CalledProcessError): @@ -103,7 +107,7 @@ class Popen(subprocess.Popen): in English. - Sets shell=True on windows by default. You can override this by forcing shell parameter to a value. - - Adds support for VOID to not buffer when not needed. + - Adds support for DEVNULL to not buffer when not needed. - Adds self.start property. Note: Popen() can throw OSError when cwd or args[0] doesn't exist. Translate @@ -121,6 +125,17 @@ def __init__(self, args, **kwargs): env = get_english_env(kwargs.get('env')) if env: kwargs['env'] = env + if kwargs.get('env') is not None and sys.version_info.major != 2: + # Subprocess expects environment variables to be strings in Python 3. + def ensure_str(value): + if isinstance(value, bytes): + return value.decode() + return value + + kwargs['env'] = { + ensure_str(k): ensure_str(v) + for k, v in kwargs['env'].items() + } if kwargs.get('shell') is None: # *Sigh*: Windows needs shell=True, or else it won't search %PATH% for # the executable, but shell=True makes subprocess on Linux fail when it's @@ -182,14 +197,16 @@ def communicate(args, **kwargs): def call(args, **kwargs): """Emulates subprocess.call(). - Automatically convert stdout=PIPE or stderr=PIPE to VOID. + Automatically convert stdout=PIPE or stderr=PIPE to DEVNULL. In no case they can be returned since no code path raises subprocess2.CalledProcessError. + + Returns exit code. """ if kwargs.get('stdout') == PIPE: - kwargs['stdout'] = VOID + kwargs['stdout'] = DEVNULL if kwargs.get('stderr') == PIPE: - kwargs['stderr'] = VOID + kwargs['stderr'] = DEVNULL return communicate(args, **kwargs)[1] @@ -219,7 +236,7 @@ def capture(args, **kwargs): - Discards returncode. - Blocks stdin by default if not specified since no output will be visible. """ - kwargs.setdefault('stdin', VOID_INPUT) + kwargs.setdefault('stdin', DEVNULL) # Like check_output, deny the caller from using stdout arg. return communicate(args, stdout=PIPE, **kwargs)[0][0] @@ -235,7 +252,7 @@ def check_output(args, **kwargs): - Blocks stdin by default if not specified since no output will be visible. - As per doc, "The stdout argument is not allowed as it is used internally." """ - kwargs.setdefault('stdin', VOID_INPUT) + kwargs.setdefault('stdin', DEVNULL) if 'stdout' in kwargs: raise ValueError('stdout argument not allowed, it would be overridden.') return check_call_out(args, stdout=PIPE, **kwargs)[0] diff --git a/tools/buildtools/win/clang-format.exe.sha1 b/tools/buildtools/win/clang-format.exe.sha1 index d31c76fe..c7efe6fb 100644 --- a/tools/buildtools/win/clang-format.exe.sha1 +++ b/tools/buildtools/win/clang-format.exe.sha1 @@ -1 +1 @@ -b5f5d8d5f8a8fcd2edb5b6cae37c0dc3e129c945 \ No newline at end of file +66882fadbf9e99cc00b8677d8c1e7e8b3cfdf4fe \ No newline at end of file diff --git a/tools/fix_style.sh b/tools/fix_style.sh index c466ab06..042c01f2 100755 --- a/tools/fix_style.sh +++ b/tools/fix_style.sh @@ -1,2 +1,2 @@ #!/bin/sh -python tools/fix_style.py $@ +python3 tools/fix_style.py $@ From 36c0b626ec0b577ae57c145e94a74cbeefbdfa2e Mon Sep 17 00:00:00 2001 From: ds58 <30220598+ds58@users.noreply.github.com> Date: Sun, 19 Feb 2023 11:56:27 -0600 Subject: [PATCH 15/75] Update CEF branch to 5359 --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0128ea84..6454cf7e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -130,7 +130,7 @@ set_property(GLOBAL PROPERTY OS_FOLDERS ON) # Specify the CEF branch if(NOT DEFINED CEF_BRANCH) - set(CEF_BRANCH "4896") + set(CEF_BRANCH "5359") endif() # Specify the CEF distribution version. From 09d44b280426fa0033bd97ec34b0ecbf49cb7bf1 Mon Sep 17 00:00:00 2001 From: GiantLuigi4 <49770992+GiantLuigi4@users.noreply.github.com> Date: Sun, 6 Aug 2023 15:47:50 -0400 Subject: [PATCH 16/75] small forge compat change, unsure exactly how necessary it'll be, but I'm putting it here incase --- .../handler/CefResourceHandlerAdapter.java | 33 ++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/java/org/cef/handler/CefResourceHandlerAdapter.java b/java/org/cef/handler/CefResourceHandlerAdapter.java index 9458bb2b..7e6e7261 100644 --- a/java/org/cef/handler/CefResourceHandlerAdapter.java +++ b/java/org/cef/handler/CefResourceHandlerAdapter.java @@ -5,6 +5,7 @@ package org.cef.handler; import org.cef.callback.CefCallback; +import org.cef.misc.BoolRef; import org.cef.misc.IntRef; import org.cef.misc.StringRef; import org.cef.network.CefCookie; @@ -17,8 +18,38 @@ * This class exists as convenience for creating handler objects. */ public abstract class CefResourceHandlerAdapter implements CefResourceHandler { + // forge causes some problems without this + private static final ClassLoader clr; + + static { + try { + // reason: prevent class loading issues with forge + Class[] LOADER = new Class[] { + IntRef.class, + BoolRef.class, + CefRequest.class, + StringRef.class, + Class.forName("org.cef.callback.CefCallback_N"), + Class.forName("org.cef.network.CefResponse_N") + }; + } catch (Throwable err) { + } + + ClassLoader c = Thread.currentThread().getContextClassLoader(); + if (c == null) c = CefResourceHandlerAdapter.class.getClassLoader(); + clr = c; + } + + /** + * override {@link CefResourceHandlerAdapter#handleRequest(CefRequest, CefCallback)} instead + */ @Override - public boolean processRequest(CefRequest request, CefCallback callback) { + public final boolean processRequest(CefRequest request, CefCallback callback) { + Thread.currentThread().setContextClassLoader(clr); // reason: prevent class loading issues with forge + return handleRequest(request, callback); + } + + public boolean handleRequest(CefRequest request, CefCallback callback) { return false; } From e4dbdea0cb8bc9f4b9c4b8c0508b8ed394f09187 Mon Sep 17 00:00:00 2001 From: GiantLuigi4 <49770992+GiantLuigi4@users.noreply.github.com> Date: Sun, 6 Aug 2023 23:06:22 -0400 Subject: [PATCH 17/75] start migrating off awt --- java/org/cef/util/CefKeyEvent.java | 32 ++++++++++++++++++++++++++++++ native/CefBrowser_N.cpp | 14 +++++++------ 2 files changed, 40 insertions(+), 6 deletions(-) create mode 100644 java/org/cef/util/CefKeyEvent.java diff --git a/java/org/cef/util/CefKeyEvent.java b/java/org/cef/util/CefKeyEvent.java new file mode 100644 index 00000000..1d073756 --- /dev/null +++ b/java/org/cef/util/CefKeyEvent.java @@ -0,0 +1,32 @@ +package org.cef.util; + +public class CefKeyEvent { + public int keyCode; + public int id; + public int modifiersEx; + public char keyChar; + public long scancode; + + public CefKeyEvent(int keyCode, int id, int modifiersEx, char keyChar) { + this.keyCode = keyCode; + this.id = id; + this.modifiersEx = modifiersEx; + this.keyChar = keyChar; + } + + public int getID() { + return id; + } + + public int getModifiersEx() { + return modifiersEx; + } + + public char getKeyChar() { + return keyChar; + } + + public int getKeyCode() { + return keyCode; + } +} diff --git a/native/CefBrowser_N.cpp b/native/CefBrowser_N.cpp index d3ece28a..5ffc3c11 100644 --- a/native/CefBrowser_N.cpp +++ b/native/CefBrowser_N.cpp @@ -12,6 +12,7 @@ #include "browser_process_handler.h" #include "client_handler.h" #include "critical_wait.h" +#include "jni_scoped_helpers.h" #include "jni_util.h" #include "life_span_handler.h" #include "pdf_print_callback.h" @@ -1600,7 +1601,8 @@ Java_org_cef_browser_CefBrowser_1N_N_1SendKeyEvent(JNIEnv* env, jobject obj, jobject key_event) { CefRefPtr browser = JNI_GET_BROWSER_OR_RETURN(env, obj); - ScopedJNIClass cls(env, env->GetObjectClass(key_event)); + ScopedJNIClass cls(env, "java/awt/event/KeyEvent"); + ScopedJNIClass objClass = ScopedJNIClass(env, env->GetObjectClass(key_event)); if (!cls) return; @@ -1610,9 +1612,9 @@ Java_org_cef_browser_CefBrowser_1N_N_1SendKeyEvent(JNIEnv* env, int event_type, modifiers; char16 key_char; - if (!CallJNIMethodI_V(env, cls, key_event, "getID", &event_type) || - !CallJNIMethodC_V(env, cls, key_event, "getKeyChar", &key_char) || - !CallJNIMethodI_V(env, cls, key_event, "getModifiersEx", &modifiers)) { + if (!CallJNIMethodI_V(env, objClass, key_event, "getID", &event_type) || + !CallJNIMethodC_V(env, objClass, key_event, "getKeyChar", &key_char) || + !CallJNIMethodI_V(env, objClass, key_event, "getModifiersEx", &modifiers)) { return; } @@ -1622,13 +1624,13 @@ Java_org_cef_browser_CefBrowser_1N_N_1SendKeyEvent(JNIEnv* env, #if defined(OS_WIN) jlong scanCode = 0; - GetJNIFieldLong(env, cls, key_event, "scancode", &scanCode); + GetJNIFieldLong(env, objClass, key_event, "scancode", &scanCode); BYTE VkCode = LOBYTE(MapVirtualKey(scanCode, MAPVK_VSC_TO_VK)); cef_event.native_key_code = (scanCode << 16) | // key scan code 1; // key repeat count #elif defined(OS_LINUX) || defined(OS_MACOSX) int key_code; - if (!CallJNIMethodI_V(env, cls, key_event, "getKeyCode", &key_code)) { + if (!CallJNIMethodI_V(env, objClass, key_event, "getKeyCode", &key_code)) { return; } From 9f3ae054c757bc7d36ca998480f853f54498dd34 Mon Sep 17 00:00:00 2001 From: GiantLuigi4 <49770992+GiantLuigi4@users.noreply.github.com> Date: Mon, 7 Aug 2023 15:26:21 -0400 Subject: [PATCH 18/75] more glfw porting --- native/CefBrowser_N.cpp | 104 ++++++++++++++++++++++++++-------------- 1 file changed, 68 insertions(+), 36 deletions(-) diff --git a/native/CefBrowser_N.cpp b/native/CefBrowser_N.cpp index 5ffc3c11..cf79f743 100644 --- a/native/CefBrowser_N.cpp +++ b/native/CefBrowser_N.cpp @@ -39,6 +39,8 @@ #undef MOUSE_MOVED #endif +#include + namespace { int GetCefModifiers(JNIEnv* env, jclass cls, int modifiers) { @@ -69,6 +71,36 @@ int GetCefModifiers(JNIEnv* env, jclass cls, int modifiers) { return cef_modifiers; } +int GetCefModifiersGlfw(JNIEnv* env, jclass cls, int modifiers) { + JNI_STATIC_DEFINE_INT_RV(env, cls, GLFW_MOD_ALT, 0); + // JNI_STATIC_DEFINE_INT_RV(env, cls, BUTTON1_DOWN_MASK, 0); + // JNI_STATIC_DEFINE_INT_RV(env, cls, BUTTON2_DOWN_MASK, 0); + // JNI_STATIC_DEFINE_INT_RV(env, cls, BUTTON3_DOWN_MASK, 0); + JNI_STATIC_DEFINE_INT_RV(env, cls, GLFW_MOD_CONTROL, 0); + JNI_STATIC_DEFINE_INT_RV(env, cls, GLFW_MOD_SUPER, 0); + JNI_STATIC_DEFINE_INT_RV(env, cls, GLFW_MOD_SHIFT, 0); + + int cef_modifiers = 0; + if (modifiers & JNI_STATIC(GLFW_MOD_ALT)) + cef_modifiers |= EVENTFLAG_ALT_DOWN; + // if (modifiers & JNI_STATIC(BUTTON1_DOWN_MASK)) + // cef_modifiers |= EVENTFLAG_LEFT_MOUSE_BUTTON; + // if (modifiers & JNI_STATIC(BUTTON2_DOWN_MASK)) + // cef_modifiers |= EVENTFLAG_MIDDLE_MOUSE_BUTTON; + // if (modifiers & JNI_STATIC(BUTTON3_DOWN_MASK)) + // cef_modifiers |= EVENTFLAG_RIGHT_MOUSE_BUTTON; + if (modifiers & JNI_STATIC(GLFW_MOD_CONTROL)) + cef_modifiers |= EVENTFLAG_CONTROL_DOWN; + if (modifiers & JNI_STATIC(GLFW_MOD_SUPER)) + cef_modifiers |= EVENTFLAG_COMMAND_DOWN; + if (modifiers & JNI_STATIC(GLFW_MOD_SHIFT)) + cef_modifiers |= EVENTFLAG_SHIFT_DOWN; + + std::cout << modifiers << ", " << cef_modifiers << "\n" << std::flush; + + return cef_modifiers; +} + #if defined(OS_LINUX) // From ui/events/keycodes/keyboard_codes_posix.h. @@ -1601,14 +1633,14 @@ Java_org_cef_browser_CefBrowser_1N_N_1SendKeyEvent(JNIEnv* env, jobject obj, jobject key_event) { CefRefPtr browser = JNI_GET_BROWSER_OR_RETURN(env, obj); - ScopedJNIClass cls(env, "java/awt/event/KeyEvent"); + ScopedJNIClass cls(env, "org/lwjgl/glfw/GLFW"); ScopedJNIClass objClass = ScopedJNIClass(env, env->GetObjectClass(key_event)); - if (!cls) + if (!cls || !objClass) return; - JNI_STATIC_DEFINE_INT(env, cls, KEY_PRESSED); - JNI_STATIC_DEFINE_INT(env, cls, KEY_RELEASED); - JNI_STATIC_DEFINE_INT(env, cls, KEY_TYPED); + JNI_STATIC_DEFINE_INT(env, cls, GLFW_PRESS); + JNI_STATIC_DEFINE_INT(env, cls, GLFW_RELEASE); + JNI_STATIC_DEFINE_INT(env, cls, GLFW_REPEAT); int event_type, modifiers; char16 key_char; @@ -1619,7 +1651,7 @@ Java_org_cef_browser_CefBrowser_1N_N_1SendKeyEvent(JNIEnv* env, } CefKeyEvent cef_event; - cef_event.modifiers = GetCefModifiers(env, cls, modifiers); + cef_event.modifiers = GetCefModifiersGlfw(env, cls, modifiers); #if defined(OS_WIN) @@ -1634,34 +1666,34 @@ Java_org_cef_browser_CefBrowser_1N_N_1SendKeyEvent(JNIEnv* env, return; } - JNI_STATIC_DEFINE_INT(env, cls, VK_BACK_SPACE); - JNI_STATIC_DEFINE_INT(env, cls, VK_DELETE); - JNI_STATIC_DEFINE_INT(env, cls, VK_DOWN); - JNI_STATIC_DEFINE_INT(env, cls, VK_ENTER); - JNI_STATIC_DEFINE_INT(env, cls, VK_ESCAPE); - JNI_STATIC_DEFINE_INT(env, cls, VK_LEFT); - JNI_STATIC_DEFINE_INT(env, cls, VK_RIGHT); - JNI_STATIC_DEFINE_INT(env, cls, VK_TAB); - JNI_STATIC_DEFINE_INT(env, cls, VK_UP); + JNI_STATIC_DEFINE_INT(env, cls, GLFW_KEY_BACKSPACE); + JNI_STATIC_DEFINE_INT(env, cls, GLFW_KEY_DELETE); + JNI_STATIC_DEFINE_INT(env, cls, GLFW_KEY_DOWN); + JNI_STATIC_DEFINE_INT(env, cls, GLFW_KEY_ENTER); + JNI_STATIC_DEFINE_INT(env, cls, GLFW_KEY_ESCAPE); + JNI_STATIC_DEFINE_INT(env, cls, GLFW_KEY_LEFT); + JNI_STATIC_DEFINE_INT(env, cls, GLFW_KEY_RIGHT); + JNI_STATIC_DEFINE_INT(env, cls, GLFW_KEY_TAB); + JNI_STATIC_DEFINE_INT(env, cls, GLFW_KEY_UP); #if defined(OS_LINUX) - if (key_code == JNI_STATIC(VK_BACK_SPACE)) + if (key_code == JNI_STATIC(GLFW_KEY_BACKSPACE)) cef_event.native_key_code = XK_BackSpace; - else if (key_code == JNI_STATIC(VK_DELETE)) + else if (key_code == JNI_STATIC(GLFW_KEY_DELETE)) cef_event.native_key_code = XK_Delete; - else if (key_code == JNI_STATIC(VK_DOWN)) + else if (key_code == JNI_STATIC(GLFW_KEY_DOWN)) cef_event.native_key_code = XK_Down; - else if (key_code == JNI_STATIC(VK_ENTER)) + else if (key_code == JNI_STATIC(GLFW_KEY_ENTER)) cef_event.native_key_code = XK_Return; - else if (key_code == JNI_STATIC(VK_ESCAPE)) + else if (key_code == JNI_STATIC(GLFW_KEY_ESCAPE)) cef_event.native_key_code = XK_Escape; - else if (key_code == JNI_STATIC(VK_LEFT)) + else if (key_code == JNI_STATIC(GLFW_KEY_LEFT)) cef_event.native_key_code = XK_Left; - else if (key_code == JNI_STATIC(VK_RIGHT)) + else if (key_code == JNI_STATIC(GLFW_KEY_RIGHT)) cef_event.native_key_code = XK_Right; - else if (key_code == JNI_STATIC(VK_TAB)) + else if (key_code == JNI_STATIC(GLFW_KEY_TAB)) cef_event.native_key_code = XK_Tab; - else if (key_code == JNI_STATIC(VK_UP)) + else if (key_code == JNI_STATIC(GLFW_KEY_UP)) cef_event.native_key_code = XK_Up; else cef_event.native_key_code = key_char; @@ -1690,31 +1722,31 @@ Java_org_cef_browser_CefBrowser_1N_N_1SendKeyEvent(JNIEnv* env, cef_event.character = cef_event.unmodified_character; } #elif defined(OS_MACOSX) - if (key_code == JNI_STATIC(VK_BACK_SPACE)) { + if (key_code == JNI_STATIC(GLFW_KEY_BACKSPACE)) { cef_event.native_key_code = kVK_Delete; cef_event.unmodified_character = kBackspaceCharCode; - } else if (key_code == JNI_STATIC(VK_DELETE)) { + } else if (key_code == JNI_STATIC(GLFW_KEY_DELETE)) { cef_event.native_key_code = kVK_ForwardDelete; cef_event.unmodified_character = kDeleteCharCode; - } else if (key_code == JNI_STATIC(VK_DOWN)) { + } else if (key_code == JNI_STATIC(GLFW_KEY_DOWN)) { cef_event.native_key_code = kVK_DownArrow; cef_event.unmodified_character = /* NSDownArrowFunctionKey */ 0xF701; - } else if (key_code == JNI_STATIC(VK_ENTER)) { + } else if (key_code == JNI_STATIC(GLFW_KEY_ENTER)) { cef_event.native_key_code = kVK_Return; cef_event.unmodified_character = kReturnCharCode; - } else if (key_code == JNI_STATIC(VK_ESCAPE)) { + } else if (key_code == JNI_STATIC(GLFW_KEY_ESCAPE)) { cef_event.native_key_code = kVK_Escape; cef_event.unmodified_character = kEscapeCharCode; - } else if (key_code == JNI_STATIC(VK_LEFT)) { + } else if (key_code == JNI_STATIC(GLFW_KEY_LEFT)) { cef_event.native_key_code = kVK_LeftArrow; cef_event.unmodified_character = /* NSLeftArrowFunctionKey */ 0xF702; - } else if (key_code == JNI_STATIC(VK_RIGHT)) { + } else if (key_code == JNI_STATIC(GLFW_KEY_RIGHT)) { cef_event.native_key_code = kVK_RightArrow; cef_event.unmodified_character = /* NSRightArrowFunctionKey */ 0xF703; - } else if (key_code == JNI_STATIC(VK_TAB)) { + } else if (key_code == JNI_STATIC(GLFW_KEY_TAB)) { cef_event.native_key_code = kVK_Tab; cef_event.unmodified_character = kTabCharCode; - } else if (key_code == JNI_STATIC(VK_UP)) { + } else if (key_code == JNI_STATIC(GLFW_KEY_UP)) { cef_event.native_key_code = kVK_UpArrow; cef_event.unmodified_character = /* NSUpArrowFunctionKey */ 0xF700; } else { @@ -1788,19 +1820,19 @@ Java_org_cef_browser_CefBrowser_1N_N_1SendKeyEvent(JNIEnv* env, #endif // defined(OS_MACOSX) #endif // defined(OS_LINUX) || defined(OS_MACOSX) - if (event_type == JNI_STATIC(KEY_PRESSED)) { + if (event_type == JNI_STATIC(GLFW_PRESS)) { #if defined(OS_WIN) cef_event.windows_key_code = VkCode; #endif cef_event.type = KEYEVENT_RAWKEYDOWN; - } else if (event_type == JNI_STATIC(KEY_RELEASED)) { + } else if (event_type == JNI_STATIC(GLFW_RELEASE)) { #if defined(OS_WIN) cef_event.windows_key_code = VkCode; // bits 30 and 31 should always be 1 for WM_KEYUP cef_event.native_key_code |= 0xC0000000; #endif cef_event.type = KEYEVENT_KEYUP; - } else if (event_type == JNI_STATIC(KEY_TYPED)) { + } else if (event_type == JNI_STATIC(GLFW_REPEAT)) { #if defined(OS_WIN) cef_event.windows_key_code = key_char; #endif From 793d6462b6ae156932e4c251bb2fd2531aec830d Mon Sep 17 00:00:00 2001 From: ds58 <30220598+ds58@users.noreply.github.com> Date: Mon, 7 Aug 2023 15:04:10 -0500 Subject: [PATCH 19/75] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index ef8fa2f2..9cb0744f 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,2 @@ -# CinemaMod java-cef -Modified version of java-cef for use with CinemaMod +# MCEF java-cef +Modified version of java-cef for use with MCEF From 1038540403d3e76fa2b7b7acdde78469723ba4de Mon Sep 17 00:00:00 2001 From: GiantLuigi4 <49770992+GiantLuigi4@users.noreply.github.com> Date: Mon, 7 Aug 2023 16:44:55 -0400 Subject: [PATCH 20/75] glfw-ify mouse events --- native/CefBrowser_N.cpp | 76 ++++++++++++++++++++--------------------- 1 file changed, 37 insertions(+), 39 deletions(-) diff --git a/native/CefBrowser_N.cpp b/native/CefBrowser_N.cpp index cf79f743..a7bac25f 100644 --- a/native/CefBrowser_N.cpp +++ b/native/CefBrowser_N.cpp @@ -73,9 +73,6 @@ int GetCefModifiers(JNIEnv* env, jclass cls, int modifiers) { int GetCefModifiersGlfw(JNIEnv* env, jclass cls, int modifiers) { JNI_STATIC_DEFINE_INT_RV(env, cls, GLFW_MOD_ALT, 0); - // JNI_STATIC_DEFINE_INT_RV(env, cls, BUTTON1_DOWN_MASK, 0); - // JNI_STATIC_DEFINE_INT_RV(env, cls, BUTTON2_DOWN_MASK, 0); - // JNI_STATIC_DEFINE_INT_RV(env, cls, BUTTON3_DOWN_MASK, 0); JNI_STATIC_DEFINE_INT_RV(env, cls, GLFW_MOD_CONTROL, 0); JNI_STATIC_DEFINE_INT_RV(env, cls, GLFW_MOD_SUPER, 0); JNI_STATIC_DEFINE_INT_RV(env, cls, GLFW_MOD_SHIFT, 0); @@ -83,12 +80,12 @@ int GetCefModifiersGlfw(JNIEnv* env, jclass cls, int modifiers) { int cef_modifiers = 0; if (modifiers & JNI_STATIC(GLFW_MOD_ALT)) cef_modifiers |= EVENTFLAG_ALT_DOWN; - // if (modifiers & JNI_STATIC(BUTTON1_DOWN_MASK)) - // cef_modifiers |= EVENTFLAG_LEFT_MOUSE_BUTTON; - // if (modifiers & JNI_STATIC(BUTTON2_DOWN_MASK)) - // cef_modifiers |= EVENTFLAG_MIDDLE_MOUSE_BUTTON; - // if (modifiers & JNI_STATIC(BUTTON3_DOWN_MASK)) - // cef_modifiers |= EVENTFLAG_RIGHT_MOUSE_BUTTON; + if (modifiers & 0x10) // BUTTON1_MASK + cef_modifiers |= EVENTFLAG_LEFT_MOUSE_BUTTON; + if (modifiers & 0x20) // BUTTON2_MASK + cef_modifiers |= EVENTFLAG_MIDDLE_MOUSE_BUTTON; + if (modifiers & 0x40) // BUTTON3_MASK + cef_modifiers |= EVENTFLAG_RIGHT_MOUSE_BUTTON; if (modifiers & JNI_STATIC(GLFW_MOD_CONTROL)) cef_modifiers |= EVENTFLAG_CONTROL_DOWN; if (modifiers & JNI_STATIC(GLFW_MOD_SUPER)) @@ -96,7 +93,7 @@ int GetCefModifiersGlfw(JNIEnv* env, jclass cls, int modifiers) { if (modifiers & JNI_STATIC(GLFW_MOD_SHIFT)) cef_modifiers |= EVENTFLAG_SHIFT_DOWN; - std::cout << modifiers << ", " << cef_modifiers << "\n" << std::flush; + std::cout << "mcef " << modifiers << "\ncef " << cef_modifiers << "\n" << std::flush; return cef_modifiers; } @@ -1849,25 +1846,22 @@ Java_org_cef_browser_CefBrowser_1N_N_1SendMouseEvent(JNIEnv* env, jobject obj, jobject mouse_event) { CefRefPtr browser = JNI_GET_BROWSER_OR_RETURN(env, obj); - ScopedJNIClass cls(env, env->GetObjectClass(mouse_event)); - if (!cls) + ScopedJNIClass cls(env, "org/lwjgl/glfw/GLFW"); + ScopedJNIClass objClass = ScopedJNIClass(env, env->GetObjectClass(mouse_event)); + if (!cls || !objClass) return; - JNI_STATIC_DEFINE_INT(env, cls, BUTTON1); - JNI_STATIC_DEFINE_INT(env, cls, BUTTON2); - JNI_STATIC_DEFINE_INT(env, cls, BUTTON3); - JNI_STATIC_DEFINE_INT(env, cls, MOUSE_DRAGGED); - JNI_STATIC_DEFINE_INT(env, cls, MOUSE_ENTERED); - JNI_STATIC_DEFINE_INT(env, cls, MOUSE_EXITED); - JNI_STATIC_DEFINE_INT(env, cls, MOUSE_MOVED); - JNI_STATIC_DEFINE_INT(env, cls, MOUSE_PRESSED); - JNI_STATIC_DEFINE_INT(env, cls, MOUSE_RELEASED); + JNI_STATIC_DEFINE_INT(env, cls, GLFW_MOUSE_BUTTON_1); + JNI_STATIC_DEFINE_INT(env, cls, GLFW_MOUSE_BUTTON_2); + JNI_STATIC_DEFINE_INT(env, cls, GLFW_MOUSE_BUTTON_3); + JNI_STATIC_DEFINE_INT(env, cls, GLFW_PRESS); + JNI_STATIC_DEFINE_INT(env, cls, GLFW_RELEASE); int event_type, x, y, modifiers; - if (!CallJNIMethodI_V(env, cls, mouse_event, "getID", &event_type) || - !CallJNIMethodI_V(env, cls, mouse_event, "getX", &x) || - !CallJNIMethodI_V(env, cls, mouse_event, "getY", &y) || - !CallJNIMethodI_V(env, cls, mouse_event, "getModifiersEx", &modifiers)) { + if (!CallJNIMethodI_V(env, objClass, mouse_event, "getID", &event_type) || + !CallJNIMethodI_V(env, objClass, mouse_event, "getX", &x) || + !CallJNIMethodI_V(env, objClass, mouse_event, "getY", &y) || + !CallJNIMethodI_V(env, objClass, mouse_event, "getModifiersEx", &modifiers)) { return; } @@ -1875,36 +1869,40 @@ Java_org_cef_browser_CefBrowser_1N_N_1SendMouseEvent(JNIEnv* env, cef_event.x = x; cef_event.y = y; - cef_event.modifiers = GetCefModifiers(env, cls, modifiers); + cef_event.modifiers = GetCefModifiersGlfw(env, cls, modifiers); - if (event_type == JNI_STATIC(MOUSE_PRESSED) || - event_type == JNI_STATIC(MOUSE_RELEASED)) { + if (event_type == JNI_STATIC(GLFW_PRESS) || + event_type == JNI_STATIC(GLFW_RELEASE)) { int click_count, button; - if (!CallJNIMethodI_V(env, cls, mouse_event, "getClickCount", + if (!CallJNIMethodI_V(env, objClass, mouse_event, "getClickCount", &click_count) || - !CallJNIMethodI_V(env, cls, mouse_event, "getButton", &button)) { + !CallJNIMethodI_V(env, objClass, mouse_event, "getButton", &button)) { return; } +std::cout << "glfw button: " << button << "\n" << std::flush; + CefBrowserHost::MouseButtonType cef_mbt; - if (button == JNI_STATIC(BUTTON1)) + if (button == JNI_STATIC(GLFW_MOUSE_BUTTON_1)) cef_mbt = MBT_LEFT; - else if (button == JNI_STATIC(BUTTON2)) + else if (button == JNI_STATIC(GLFW_MOUSE_BUTTON_2)) cef_mbt = MBT_MIDDLE; - else if (button == JNI_STATIC(BUTTON3)) + else if (button == JNI_STATIC(GLFW_MOUSE_BUTTON_3)) cef_mbt = MBT_RIGHT; else return; +std::cout << "cef button: " << cef_mbt << "\n" << std::flush; + browser->GetHost()->SendMouseClickEvent( - cef_event, cef_mbt, (event_type == JNI_STATIC(MOUSE_RELEASED)), + cef_event, cef_mbt, (event_type == JNI_STATIC(GLFW_RELEASE)), click_count); - } else if (event_type == JNI_STATIC(MOUSE_MOVED) || - event_type == JNI_STATIC(MOUSE_DRAGGED) || - event_type == JNI_STATIC(MOUSE_ENTERED) || - event_type == JNI_STATIC(MOUSE_EXITED)) { + } else if (event_type == 503 || // MOUSE_MOVED + event_type == 506 || // MOUSE_DRAGGED + event_type == 504 || // MOUSE_ENTERED + event_type == 505) { // MOUSE_EXITED browser->GetHost()->SendMouseMoveEvent( - cef_event, (event_type == JNI_STATIC(MOUSE_EXITED))); + cef_event, (event_type == 505)); // MOUSE_EXITED } } From 9f7881590ac67ce60bd8e0577a45c34daff8286c Mon Sep 17 00:00:00 2001 From: GiantLuigi4 <49770992+GiantLuigi4@users.noreply.github.com> Date: Mon, 7 Aug 2023 18:56:13 -0400 Subject: [PATCH 21/75] should be done with the events may be a good idea to remove some awt references in setup and drag&drop --- java/org/cef/browser/CefBrowser_N.java | 19 ++++---- java/org/cef/{util => event}/CefKeyEvent.java | 2 +- java/org/cef/event/CefMouseEvent.java | 48 +++++++++++++++++++ java/org/cef/event/CefMouseWheelEvent.java | 41 ++++++++++++++++ native/CefBrowser_N.cpp | 32 +++++-------- 5 files changed, 111 insertions(+), 31 deletions(-) rename java/org/cef/{util => event}/CefKeyEvent.java (96%) create mode 100644 java/org/cef/event/CefMouseEvent.java create mode 100644 java/org/cef/event/CefMouseWheelEvent.java diff --git a/java/org/cef/browser/CefBrowser_N.java b/java/org/cef/browser/CefBrowser_N.java index cebcaa75..f3ad8f9f 100644 --- a/java/org/cef/browser/CefBrowser_N.java +++ b/java/org/cef/browser/CefBrowser_N.java @@ -11,6 +11,9 @@ import org.cef.callback.CefPdfPrintCallback; import org.cef.callback.CefRunFileDialogCallback; import org.cef.callback.CefStringVisitor; +import org.cef.event.CefKeyEvent; +import org.cef.event.CefMouseEvent; +import org.cef.event.CefMouseWheelEvent; import org.cef.handler.CefClientHandler; import org.cef.handler.CefDialogHandler.FileDialogMode; import org.cef.handler.CefRenderHandler; @@ -18,14 +21,10 @@ import org.cef.misc.CefPdfPrintSettings; import org.cef.network.CefRequest; -import java.awt.Canvas; import java.awt.Component; import java.awt.Point; import java.awt.Rectangle; import java.awt.Window; -import java.awt.event.KeyEvent; -import java.awt.event.MouseEvent; -import java.awt.event.MouseWheelEvent; import java.awt.event.WindowEvent; import java.util.Vector; @@ -595,7 +594,7 @@ protected final void invalidate() { * Send a key event. * @param e The event to send. */ - protected final void sendKeyEvent(KeyEvent e) { + protected final void sendKeyEvent(CefKeyEvent e) { try { N_SendKeyEvent(e); } catch (UnsatisfiedLinkError ule) { @@ -607,7 +606,7 @@ protected final void sendKeyEvent(KeyEvent e) { * Send a mouse event. * @param e The event to send. */ - protected final void sendMouseEvent(MouseEvent e) { + protected final void sendMouseEvent(CefMouseEvent e) { try { N_SendMouseEvent(e); } catch (UnsatisfiedLinkError ule) { @@ -619,7 +618,7 @@ protected final void sendMouseEvent(MouseEvent e) { * Send a mouse wheel event. * @param e The event to send. */ - protected final void sendMouseWheelEvent(MouseWheelEvent e) { + protected final void sendMouseWheelEvent(CefMouseWheelEvent e) { try { N_SendMouseWheelEvent(e); } catch (UnsatisfiedLinkError ule) { @@ -801,9 +800,9 @@ private final native void N_Find( private final native void N_ReplaceMisspelling(String word); private final native void N_WasResized(int width, int height); private final native void N_Invalidate(); - private final native void N_SendKeyEvent(KeyEvent e); - private final native void N_SendMouseEvent(MouseEvent e); - private final native void N_SendMouseWheelEvent(MouseWheelEvent e); + private final native void N_SendKeyEvent(CefKeyEvent e); + private final native void N_SendMouseEvent(CefMouseEvent e); + private final native void N_SendMouseWheelEvent(CefMouseWheelEvent e); private final native void N_DragTargetDragEnter( CefDragData dragData, Point pos, int modifiers, int allowed_ops); private final native void N_DragTargetDragOver(Point pos, int modifiers, int allowed_ops); diff --git a/java/org/cef/util/CefKeyEvent.java b/java/org/cef/event/CefKeyEvent.java similarity index 96% rename from java/org/cef/util/CefKeyEvent.java rename to java/org/cef/event/CefKeyEvent.java index 1d073756..4eabd5a7 100644 --- a/java/org/cef/util/CefKeyEvent.java +++ b/java/org/cef/event/CefKeyEvent.java @@ -1,4 +1,4 @@ -package org.cef.util; +package org.cef.event; public class CefKeyEvent { public int keyCode; diff --git a/java/org/cef/event/CefMouseEvent.java b/java/org/cef/event/CefMouseEvent.java new file mode 100644 index 00000000..86cffbb2 --- /dev/null +++ b/java/org/cef/event/CefMouseEvent.java @@ -0,0 +1,48 @@ +package org.cef.event; + +public class CefMouseEvent { + public static final int MOUSE_MOVED = 502; + public static final int BUTTON1_MASK = 0x10; + public static final int BUTTON2_MASK = 0x20; + public static final int BUTTON3_MASK = 0x40; + + public int id; + public int x; + public int y; + public int modifs; + public int clickCount; + public int button; + + public CefMouseEvent(int id, int x, int y, int modifs, int clickCount, int button) { + this.id = id; + this.x = x; + this.y = y; + this.modifs = modifs; + this.clickCount = clickCount; + this.button = button; + } + + public int getID() { + return id; + } + + public int getX() { + return x; + } + + public int getY() { + return y; + } + + public int getModifiersEx() { + return modifs; + } + + public int getClickCount() { + return clickCount; + } + + public int getButton() { + return button; + } +} diff --git a/java/org/cef/event/CefMouseWheelEvent.java b/java/org/cef/event/CefMouseWheelEvent.java new file mode 100644 index 00000000..14cc5bac --- /dev/null +++ b/java/org/cef/event/CefMouseWheelEvent.java @@ -0,0 +1,41 @@ +package org.cef.event; + +public class CefMouseWheelEvent { + public static final int WHEEL_UNIT_SCROLL = 0; + public static final int WHEEL_BLOCK_SCROLL = 1; + + int id, delta, x, y, modifiers; + int amount = 32; // TODO: might want to make this change dependent on system? + + public CefMouseWheelEvent(int id, int delta, int x, int y, int modifiers) { + this.id = id; + this.delta = delta; + this.x = x; + this.y = y; + this.modifiers = modifiers; + } + + public int getScrollType() { + return id; + } + + public int getWheelRotation() { + return delta; + } + + public int getX() { + return x; + } + + public int getY() { + return y; + } + + public int getModifiersEx() { + return modifiers; + } + + public int getUnitsToScroll() { + return amount * delta; + } +} diff --git a/native/CefBrowser_N.cpp b/native/CefBrowser_N.cpp index a7bac25f..6067e192 100644 --- a/native/CefBrowser_N.cpp +++ b/native/CefBrowser_N.cpp @@ -39,8 +39,6 @@ #undef MOUSE_MOVED #endif -#include - namespace { int GetCefModifiers(JNIEnv* env, jclass cls, int modifiers) { @@ -93,8 +91,6 @@ int GetCefModifiersGlfw(JNIEnv* env, jclass cls, int modifiers) { if (modifiers & JNI_STATIC(GLFW_MOD_SHIFT)) cef_modifiers |= EVENTFLAG_SHIFT_DOWN; - std::cout << "mcef " << modifiers << "\ncef " << cef_modifiers << "\n" << std::flush; - return cef_modifiers; } @@ -1651,7 +1647,6 @@ Java_org_cef_browser_CefBrowser_1N_N_1SendKeyEvent(JNIEnv* env, cef_event.modifiers = GetCefModifiersGlfw(env, cls, modifiers); #if defined(OS_WIN) - jlong scanCode = 0; GetJNIFieldLong(env, objClass, key_event, "scancode", &scanCode); BYTE VkCode = LOBYTE(MapVirtualKey(scanCode, MAPVK_VSC_TO_VK)); @@ -1880,8 +1875,6 @@ Java_org_cef_browser_CefBrowser_1N_N_1SendMouseEvent(JNIEnv* env, return; } -std::cout << "glfw button: " << button << "\n" << std::flush; - CefBrowserHost::MouseButtonType cef_mbt; if (button == JNI_STATIC(GLFW_MOUSE_BUTTON_1)) cef_mbt = MBT_LEFT; @@ -1892,8 +1885,6 @@ std::cout << "glfw button: " << button << "\n" << std::flush; else return; -std::cout << "cef button: " << cef_mbt << "\n" << std::flush; - browser->GetHost()->SendMouseClickEvent( cef_event, cef_mbt, (event_type == JNI_STATIC(GLFW_RELEASE)), click_count); @@ -1912,20 +1903,21 @@ Java_org_cef_browser_CefBrowser_1N_N_1SendMouseWheelEvent( jobject obj, jobject mouse_wheel_event) { CefRefPtr browser = JNI_GET_BROWSER_OR_RETURN(env, obj); - ScopedJNIClass cls(env, env->GetObjectClass(mouse_wheel_event)); - if (!cls) + ScopedJNIClass cls(env, "org/lwjgl/glfw/GLFW"); + ScopedJNIClass objClass = ScopedJNIClass(env, env->GetObjectClass(mouse_wheel_event)); + if (!cls || !objClass) return; - JNI_STATIC_DEFINE_INT(env, cls, WHEEL_UNIT_SCROLL); + JNI_STATIC_DEFINE_INT(env, objClass, WHEEL_UNIT_SCROLL); int scroll_type, delta, x, y, modifiers; - if (!CallJNIMethodI_V(env, cls, mouse_wheel_event, "getScrollType", + if (!CallJNIMethodI_V(env, objClass, mouse_wheel_event, "getScrollType", &scroll_type) || - !CallJNIMethodI_V(env, cls, mouse_wheel_event, "getWheelRotation", + !CallJNIMethodI_V(env, objClass, mouse_wheel_event, "getWheelRotation", &delta) || - !CallJNIMethodI_V(env, cls, mouse_wheel_event, "getX", &x) || - !CallJNIMethodI_V(env, cls, mouse_wheel_event, "getY", &y) || - !CallJNIMethodI_V(env, cls, mouse_wheel_event, "getModifiersEx", + !CallJNIMethodI_V(env, objClass, mouse_wheel_event, "getX", &x) || + !CallJNIMethodI_V(env, objClass, mouse_wheel_event, "getY", &y) || + !CallJNIMethodI_V(env, objClass, mouse_wheel_event, "getModifiersEx", &modifiers)) { return; } @@ -1934,11 +1926,11 @@ Java_org_cef_browser_CefBrowser_1N_N_1SendMouseWheelEvent( cef_event.x = x; cef_event.y = y; - cef_event.modifiers = GetCefModifiers(env, cls, modifiers); + cef_event.modifiers = GetCefModifiersGlfw(env, cls, modifiers); - if (scroll_type == JNI_STATIC(WHEEL_UNIT_SCROLL)) { + if (scroll_type == 0) { // Use the smarter version that considers platform settings. - CallJNIMethodI_V(env, cls, mouse_wheel_event, "getUnitsToScroll", &delta); + CallJNIMethodI_V(env, objClass, mouse_wheel_event, "getUnitsToScroll", &delta); } double deltaX = 0, deltaY = 0; From 63ee43e4985335c1b193b639a684e5af3fcccea9 Mon Sep 17 00:00:00 2001 From: GiantLuigi4 <49770992+GiantLuigi4@users.noreply.github.com> Date: Mon, 7 Aug 2023 18:57:49 -0400 Subject: [PATCH 22/75] actually, I'll undo this for now --- .../handler/CefResourceHandlerAdapter.java | 32 +------------------ 1 file changed, 1 insertion(+), 31 deletions(-) diff --git a/java/org/cef/handler/CefResourceHandlerAdapter.java b/java/org/cef/handler/CefResourceHandlerAdapter.java index 7e6e7261..916cf52a 100644 --- a/java/org/cef/handler/CefResourceHandlerAdapter.java +++ b/java/org/cef/handler/CefResourceHandlerAdapter.java @@ -18,38 +18,8 @@ * This class exists as convenience for creating handler objects. */ public abstract class CefResourceHandlerAdapter implements CefResourceHandler { - // forge causes some problems without this - private static final ClassLoader clr; - - static { - try { - // reason: prevent class loading issues with forge - Class[] LOADER = new Class[] { - IntRef.class, - BoolRef.class, - CefRequest.class, - StringRef.class, - Class.forName("org.cef.callback.CefCallback_N"), - Class.forName("org.cef.network.CefResponse_N") - }; - } catch (Throwable err) { - } - - ClassLoader c = Thread.currentThread().getContextClassLoader(); - if (c == null) c = CefResourceHandlerAdapter.class.getClassLoader(); - clr = c; - } - - /** - * override {@link CefResourceHandlerAdapter#handleRequest(CefRequest, CefCallback)} instead - */ @Override - public final boolean processRequest(CefRequest request, CefCallback callback) { - Thread.currentThread().setContextClassLoader(clr); // reason: prevent class loading issues with forge - return handleRequest(request, callback); - } - - public boolean handleRequest(CefRequest request, CefCallback callback) { + public boolean processRequest(CefRequest request, CefCallback callback) { return false; } From ebf4292289d6bc5faa11053ccc4f6875cb93024e Mon Sep 17 00:00:00 2001 From: GiantLuigi4 <49770992+GiantLuigi4@users.noreply.github.com> Date: Mon, 7 Aug 2023 20:32:44 -0400 Subject: [PATCH 23/75] realized this is useful --- java/org/cef/event/CefMouseEvent.java | 1 + 1 file changed, 1 insertion(+) diff --git a/java/org/cef/event/CefMouseEvent.java b/java/org/cef/event/CefMouseEvent.java index 86cffbb2..40214cef 100644 --- a/java/org/cef/event/CefMouseEvent.java +++ b/java/org/cef/event/CefMouseEvent.java @@ -2,6 +2,7 @@ public class CefMouseEvent { public static final int MOUSE_MOVED = 502; + public static final int MOUSE_DRAGGED = 506; public static final int BUTTON1_MASK = 0x10; public static final int BUTTON2_MASK = 0x20; public static final int BUTTON3_MASK = 0x40; From 719493d0be904b2e54062d285c7410111fc4bf29 Mon Sep 17 00:00:00 2001 From: GiantLuigi4 <49770992+GiantLuigi4@users.noreply.github.com> Date: Mon, 7 Aug 2023 20:37:39 -0400 Subject: [PATCH 24/75] realized that only mouse exit and mouse move is meaningful --- java/org/cef/event/CefMouseEvent.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/org/cef/event/CefMouseEvent.java b/java/org/cef/event/CefMouseEvent.java index 40214cef..c071cbdd 100644 --- a/java/org/cef/event/CefMouseEvent.java +++ b/java/org/cef/event/CefMouseEvent.java @@ -2,7 +2,7 @@ public class CefMouseEvent { public static final int MOUSE_MOVED = 502; - public static final int MOUSE_DRAGGED = 506; + public static final int MOUSE_EXIT = 505; public static final int BUTTON1_MASK = 0x10; public static final int BUTTON2_MASK = 0x20; public static final int BUTTON3_MASK = 0x40; From 97173bb0cef11faf64eabc954b41e836f5e6c3a9 Mon Sep 17 00:00:00 2001 From: GiantLuigi4 <49770992+GiantLuigi4@users.noreply.github.com> Date: Mon, 7 Aug 2023 20:49:28 -0400 Subject: [PATCH 25/75] variables for key constants, add basic notes on what the constants are --- java/org/cef/event/CefKeyEvent.java | 5 +++++ java/org/cef/event/CefMouseEvent.java | 2 ++ java/org/cef/event/CefMouseWheelEvent.java | 1 + 3 files changed, 8 insertions(+) diff --git a/java/org/cef/event/CefKeyEvent.java b/java/org/cef/event/CefKeyEvent.java index 4eabd5a7..ed0b5688 100644 --- a/java/org/cef/event/CefKeyEvent.java +++ b/java/org/cef/event/CefKeyEvent.java @@ -1,6 +1,11 @@ package org.cef.event; public class CefKeyEvent { + /* id constants */ + public static final int KEY_PRESS = 1; + public static final int KEY_RELEASE = 0; + public static final int KEY_TYPE = 2; + public int keyCode; public int id; public int modifiersEx; diff --git a/java/org/cef/event/CefMouseEvent.java b/java/org/cef/event/CefMouseEvent.java index c071cbdd..f7c074f6 100644 --- a/java/org/cef/event/CefMouseEvent.java +++ b/java/org/cef/event/CefMouseEvent.java @@ -1,8 +1,10 @@ package org.cef.event; public class CefMouseEvent { + /* id constants */ public static final int MOUSE_MOVED = 502; public static final int MOUSE_EXIT = 505; + /* modifier constants */ public static final int BUTTON1_MASK = 0x10; public static final int BUTTON2_MASK = 0x20; public static final int BUTTON3_MASK = 0x40; diff --git a/java/org/cef/event/CefMouseWheelEvent.java b/java/org/cef/event/CefMouseWheelEvent.java index 14cc5bac..54e32867 100644 --- a/java/org/cef/event/CefMouseWheelEvent.java +++ b/java/org/cef/event/CefMouseWheelEvent.java @@ -1,6 +1,7 @@ package org.cef.event; public class CefMouseWheelEvent { + /* id constants */ public static final int WHEEL_UNIT_SCROLL = 0; public static final int WHEEL_BLOCK_SCROLL = 1; From ab05420d120ee2d6905c14ef2152ec8daa6daf64 Mon Sep 17 00:00:00 2001 From: GiantLuigi4 <49770992+GiantLuigi4@users.noreply.github.com> Date: Mon, 7 Aug 2023 21:38:18 -0400 Subject: [PATCH 26/75] apparently I messed this number up --- java/org/cef/event/CefMouseEvent.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/org/cef/event/CefMouseEvent.java b/java/org/cef/event/CefMouseEvent.java index f7c074f6..a16f358c 100644 --- a/java/org/cef/event/CefMouseEvent.java +++ b/java/org/cef/event/CefMouseEvent.java @@ -2,7 +2,7 @@ public class CefMouseEvent { /* id constants */ - public static final int MOUSE_MOVED = 502; + public static final int MOUSE_MOVED = 503; public static final int MOUSE_EXIT = 505; /* modifier constants */ public static final int BUTTON1_MASK = 0x10; From e86d2640635440c580602835d5bee5c0838a2caf Mon Sep 17 00:00:00 2001 From: GiantLuigi4 <49770992+GiantLuigi4@users.noreply.github.com> Date: Mon, 7 Aug 2023 22:38:11 -0400 Subject: [PATCH 27/75] follow ds's comments --- java/org/cef/event/CefKeyEvent.java | 15 +++++++++------ java/org/cef/event/CefMouseEvent.java | 13 ++++++++----- java/org/cef/event/CefMouseWheelEvent.java | 19 +++++++++++++------ native/CefBrowser_N.cpp | 6 +++--- 4 files changed, 33 insertions(+), 20 deletions(-) diff --git a/java/org/cef/event/CefKeyEvent.java b/java/org/cef/event/CefKeyEvent.java index ed0b5688..eda2a84c 100644 --- a/java/org/cef/event/CefKeyEvent.java +++ b/java/org/cef/event/CefKeyEvent.java @@ -6,25 +6,28 @@ public class CefKeyEvent { public static final int KEY_RELEASE = 0; public static final int KEY_TYPE = 2; + // intentionally leaving these public for now + // may remove the getters, or maybe add setters, or maybe move to private + // not sure yet public int keyCode; public int id; - public int modifiersEx; + public int modifiers; public char keyChar; public long scancode; - public CefKeyEvent(int keyCode, int id, int modifiersEx, char keyChar) { - this.keyCode = keyCode; + public CefKeyEvent(int id, int keyCode, char keyChar, int modifiers) { this.id = id; - this.modifiersEx = modifiersEx; + this.keyCode = keyCode; this.keyChar = keyChar; + this.modifiers = modifiers; } public int getID() { return id; } - public int getModifiersEx() { - return modifiersEx; + public int getModifiers() { + return modifiers; } public char getKeyChar() { diff --git a/java/org/cef/event/CefMouseEvent.java b/java/org/cef/event/CefMouseEvent.java index a16f358c..23840478 100644 --- a/java/org/cef/event/CefMouseEvent.java +++ b/java/org/cef/event/CefMouseEvent.java @@ -9,20 +9,23 @@ public class CefMouseEvent { public static final int BUTTON2_MASK = 0x20; public static final int BUTTON3_MASK = 0x40; + // intentionally leaving these public for now + // may remove the getters, or maybe add setters, or maybe move to private + // not sure yet public int id; public int x; public int y; - public int modifs; + public int modifiers; public int clickCount; public int button; - public CefMouseEvent(int id, int x, int y, int modifs, int clickCount, int button) { + public CefMouseEvent(int id, int x, int y, int clickCount, int button, int modifiers) { this.id = id; this.x = x; this.y = y; - this.modifs = modifs; this.clickCount = clickCount; this.button = button; + this.modifiers = modifiers; } public int getID() { @@ -37,8 +40,8 @@ public int getY() { return y; } - public int getModifiersEx() { - return modifs; + public int getModifiers() { + return modifiers; } public int getClickCount() { diff --git a/java/org/cef/event/CefMouseWheelEvent.java b/java/org/cef/event/CefMouseWheelEvent.java index 54e32867..54a46f23 100644 --- a/java/org/cef/event/CefMouseWheelEvent.java +++ b/java/org/cef/event/CefMouseWheelEvent.java @@ -5,14 +5,21 @@ public class CefMouseWheelEvent { public static final int WHEEL_UNIT_SCROLL = 0; public static final int WHEEL_BLOCK_SCROLL = 1; - int id, delta, x, y, modifiers; - int amount = 32; // TODO: might want to make this change dependent on system? - - public CefMouseWheelEvent(int id, int delta, int x, int y, int modifiers) { + // intentionally leaving these public for now + // may remove the getters, or maybe add setters, or maybe move to private + // not sure yet + public int id; + public int delta; + public int x; + public int y; + public int modifiers; + public int amount = 32; // TODO: might want to make this change dependent on system? + + public CefMouseWheelEvent(int id, int x, int y, int delta, int modifiers) { this.id = id; - this.delta = delta; this.x = x; this.y = y; + this.delta = delta; this.modifiers = modifiers; } @@ -32,7 +39,7 @@ public int getY() { return y; } - public int getModifiersEx() { + public int getModifiers() { return modifiers; } diff --git a/native/CefBrowser_N.cpp b/native/CefBrowser_N.cpp index 6067e192..c57b0d6c 100644 --- a/native/CefBrowser_N.cpp +++ b/native/CefBrowser_N.cpp @@ -1639,7 +1639,7 @@ Java_org_cef_browser_CefBrowser_1N_N_1SendKeyEvent(JNIEnv* env, char16 key_char; if (!CallJNIMethodI_V(env, objClass, key_event, "getID", &event_type) || !CallJNIMethodC_V(env, objClass, key_event, "getKeyChar", &key_char) || - !CallJNIMethodI_V(env, objClass, key_event, "getModifiersEx", &modifiers)) { + !CallJNIMethodI_V(env, objClass, key_event, "getModifiers", &modifiers)) { return; } @@ -1856,7 +1856,7 @@ Java_org_cef_browser_CefBrowser_1N_N_1SendMouseEvent(JNIEnv* env, if (!CallJNIMethodI_V(env, objClass, mouse_event, "getID", &event_type) || !CallJNIMethodI_V(env, objClass, mouse_event, "getX", &x) || !CallJNIMethodI_V(env, objClass, mouse_event, "getY", &y) || - !CallJNIMethodI_V(env, objClass, mouse_event, "getModifiersEx", &modifiers)) { + !CallJNIMethodI_V(env, objClass, mouse_event, "getModifiers", &modifiers)) { return; } @@ -1917,7 +1917,7 @@ Java_org_cef_browser_CefBrowser_1N_N_1SendMouseWheelEvent( &delta) || !CallJNIMethodI_V(env, objClass, mouse_wheel_event, "getX", &x) || !CallJNIMethodI_V(env, objClass, mouse_wheel_event, "getY", &y) || - !CallJNIMethodI_V(env, objClass, mouse_wheel_event, "getModifiersEx", + !CallJNIMethodI_V(env, objClass, mouse_wheel_event, "getModifiers", &modifiers)) { return; } From 2fddac22c7dc8cca78303422aa3b0fc976f6b890 Mon Sep 17 00:00:00 2001 From: GiantLuigi4 <49770992+GiantLuigi4@users.noreply.github.com> Date: Tue, 8 Aug 2023 12:31:41 -0400 Subject: [PATCH 28/75] cleanup --- java/org/cef/handler/CefResourceHandlerAdapter.java | 2 -- native/CefBrowser_N.cpp | 3 +-- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/java/org/cef/handler/CefResourceHandlerAdapter.java b/java/org/cef/handler/CefResourceHandlerAdapter.java index 916cf52a..9c349f6e 100644 --- a/java/org/cef/handler/CefResourceHandlerAdapter.java +++ b/java/org/cef/handler/CefResourceHandlerAdapter.java @@ -5,10 +5,8 @@ package org.cef.handler; import org.cef.callback.CefCallback; -import org.cef.misc.BoolRef; import org.cef.misc.IntRef; import org.cef.misc.StringRef; -import org.cef.network.CefCookie; import org.cef.network.CefRequest; import org.cef.network.CefResponse; diff --git a/native/CefBrowser_N.cpp b/native/CefBrowser_N.cpp index c57b0d6c..c5716b89 100644 --- a/native/CefBrowser_N.cpp +++ b/native/CefBrowser_N.cpp @@ -12,7 +12,6 @@ #include "browser_process_handler.h" #include "client_handler.h" #include "critical_wait.h" -#include "jni_scoped_helpers.h" #include "jni_util.h" #include "life_span_handler.h" #include "pdf_print_callback.h" @@ -1928,7 +1927,7 @@ Java_org_cef_browser_CefBrowser_1N_N_1SendMouseWheelEvent( cef_event.modifiers = GetCefModifiersGlfw(env, cls, modifiers); - if (scroll_type == 0) { + if (scroll_type == 0) { // WHEEL_UNIT_SCROLL // Use the smarter version that considers platform settings. CallJNIMethodI_V(env, objClass, mouse_wheel_event, "getUnitsToScroll", &delta); } From df8a6670c2883528d847ca8e26880ba69f8523b0 Mon Sep 17 00:00:00 2001 From: GiantLuigi4 <49770992+GiantLuigi4@users.noreply.github.com> Date: Tue, 8 Aug 2023 18:22:54 -0400 Subject: [PATCH 29/75] remove need for awt canvas --- native/CefBrowser_N.cpp | 81 ++--------------------------------------- native/CefBrowser_N.h | 12 ------ 2 files changed, 3 insertions(+), 90 deletions(-) diff --git a/native/CefBrowser_N.cpp b/native/CefBrowser_N.cpp index c5716b89..583107af 100644 --- a/native/CefBrowser_N.cpp +++ b/native/CefBrowser_N.cpp @@ -921,7 +921,6 @@ struct JNIObjectsForCreate { ScopedJNIObjectGlobal jparentBrowser; ScopedJNIObjectGlobal jclientHandler; ScopedJNIObjectGlobal url; - ScopedJNIObjectGlobal canvas; ScopedJNIObjectGlobal jcontext; ScopedJNIObjectGlobal jinspectAt; @@ -930,7 +929,6 @@ struct JNIObjectsForCreate { jobject _jparentBrowser, jobject _jclientHandler, jstring _url, - jobject _canvas, jobject _jcontext, jobject _jinspectAt) : @@ -939,7 +937,6 @@ struct JNIObjectsForCreate { jparentBrowser(env, _jparentBrowser), jclientHandler(env, _jclientHandler), url(env, _url), - canvas(env, _canvas), jcontext(env, _jcontext), jinspectAt(env, _jinspectAt) {} }; @@ -960,42 +957,7 @@ void create(std::shared_ptr objs, return; CefWindowInfo windowInfo; - if (osr == JNI_FALSE) { - CefRect rect; - CefRefPtr windowHandler = - (WindowHandler*)clientHandler->GetWindowHandler().get(); - if (windowHandler.get()) { - windowHandler->GetRect(objs->jbrowser, rect); - } -#if defined(OS_WIN) - CefWindowHandle parent = TempWindow::GetWindowHandle(); - if (objs->canvas != nullptr) { - parent = GetHwndOfCanvas(objs->canvas, env); - } else { - // Do not activate hidden browser windows on creation. - windowInfo.ex_style |= WS_EX_NOACTIVATE; - } - windowInfo.SetAsChild(parent, rect); -#elif defined(OS_MACOSX) - NSWindow* parent = nullptr; - if (windowHandle != 0) { - parent = (NSWindow*)windowHandle; - } else { - parent = TempWindow::GetWindow(); - } - CefWindowHandle browserContentView = - util_mac::CreateBrowserContentView(parent, rect); - windowInfo.SetAsChild(browserContentView, rect); -#elif defined(OS_LINUX) - CefWindowHandle parent = TempWindow::GetWindowHandle(); - if (objs->canvas != nullptr) { - parent = GetDrawableOfCanvas(objs->canvas, env); - } - windowInfo.SetAsChild(parent, rect); -#endif - } else { - windowInfo.SetAsWindowless((CefWindowHandle)windowHandle); - } + windowInfo.SetAsWindowless((CefWindowHandle)windowHandle); CefBrowserSettings settings; @@ -1173,10 +1135,9 @@ Java_org_cef_browser_CefBrowser_1N_N_1CreateBrowser(JNIEnv* env, jstring url, jboolean osr, jboolean transparent, - jobject canvas, jobject jcontext) { std::shared_ptr objs(new JNIObjectsForCreate( - env, jbrowser, nullptr, jclientHandler, url, canvas, jcontext, nullptr)); + env, jbrowser, nullptr, jclientHandler, url, jcontext, nullptr)); if (CefCurrentlyOn(TID_UI)) { create(objs, windowHandle, osr, transparent); } else { @@ -1194,11 +1155,10 @@ Java_org_cef_browser_CefBrowser_1N_N_1CreateDevTools(JNIEnv* env, jlong windowHandle, jboolean osr, jboolean transparent, - jobject canvas, jobject inspect) { std::shared_ptr objs( new JNIObjectsForCreate(env, jbrowser, jparent, jclientHandler, nullptr, - canvas, nullptr, inspect)); + nullptr, inspect)); if (CefCurrentlyOn(TID_UI)) { create(objs, windowHandle, osr, transparent); } else { @@ -2049,41 +2009,6 @@ Java_org_cef_browser_CefBrowser_1N_N_1UpdateUI(JNIEnv* env, #endif } -JNIEXPORT void JNICALL -Java_org_cef_browser_CefBrowser_1N_N_1SetParent(JNIEnv* env, - jobject obj, - jlong windowHandle, - jobject canvas) { - CefRefPtr browser = JNI_GET_BROWSER_OR_RETURN(env, obj); - base::OnceClosure callback = base::BindOnce(&OnAfterParentChanged, browser); - -#if defined(OS_MACOSX) - util::SetParent(browser->GetHost()->GetWindowHandle(), windowHandle, - std::move(callback)); -#else - CefWindowHandle browserHandle = browser->GetHost()->GetWindowHandle(); - CefWindowHandle parentHandle = - canvas ? util::GetWindowHandle(env, canvas) : kNullWindowHandle; - if (CefCurrentlyOn(TID_UI)) { - util::SetParent(browserHandle, parentHandle, std::move(callback)); - } else { -#if defined(OS_LINUX) - CriticalLock lock; - CriticalWait waitCond(&lock); - lock.Lock(); - CefPostTask(TID_UI, - base::BindOnce(util::SetParentSync, browserHandle, parentHandle, - &waitCond, std::move(callback))); - waitCond.Wait(1000); - lock.Unlock(); -#else - CefPostTask(TID_UI, base::BindOnce(util::SetParent, browserHandle, - parentHandle, std::move(callback))); -#endif - } -#endif -} - JNIEXPORT void JNICALL Java_org_cef_browser_CefBrowser_1N_N_1NotifyMoveOrResizeStarted(JNIEnv* env, jobject obj) { diff --git a/native/CefBrowser_N.h b/native/CefBrowser_N.h index 9e03d8ca..bd0fd0d0 100644 --- a/native/CefBrowser_N.h +++ b/native/CefBrowser_N.h @@ -21,7 +21,6 @@ Java_org_cef_browser_CefBrowser_1N_N_1CreateBrowser(JNIEnv*, jstring, jboolean, jboolean, - jobject, jobject); /* @@ -38,7 +37,6 @@ Java_org_cef_browser_CefBrowser_1N_N_1CreateDevTools(JNIEnv*, jlong, jboolean, jboolean, - jobject, jobject); /* @@ -501,16 +499,6 @@ JNIEXPORT void JNICALL Java_org_cef_browser_CefBrowser_1N_N_1UpdateUI(JNIEnv*, jobject, jobject); -/* - * Class: org_cef_browser_CefBrowser_N - * Method: N_SetParent - * Signature: (JLjava/awt/Component;)V - */ -JNIEXPORT void JNICALL Java_org_cef_browser_CefBrowser_1N_N_1SetParent(JNIEnv*, - jobject, - jlong, - jobject); - /* * Class: org_cef_browser_CefBrowser_N * Method: N_NotifyMoveOrResizeStarted From e10d321a53c36545e5329cd82d7a1bce31f5cb0b Mon Sep 17 00:00:00 2001 From: GiantLuigi4 <49770992+GiantLuigi4@users.noreply.github.com> Date: Tue, 8 Aug 2023 20:41:21 -0400 Subject: [PATCH 30/75] no awt, except for in like drag events --- java/org/cef/browser/CefBrowserFactory.java | 5 +- java/org/cef/browser/CefBrowserOsr.java | 4 +- java/org/cef/browser/CefBrowserWr.java | 424 -------------------- java/org/cef/browser/CefBrowser_N.java | 23 +- 4 files changed, 10 insertions(+), 446 deletions(-) delete mode 100644 java/org/cef/browser/CefBrowserWr.java diff --git a/java/org/cef/browser/CefBrowserFactory.java b/java/org/cef/browser/CefBrowserFactory.java index 708d0f24..98a1678e 100644 --- a/java/org/cef/browser/CefBrowserFactory.java +++ b/java/org/cef/browser/CefBrowserFactory.java @@ -10,9 +10,8 @@ * Creates a new instance of CefBrowser according the passed values */ public class CefBrowserFactory { - public static CefBrowser create(CefClient client, String url, boolean isOffscreenRendered, + public static CefBrowser create(CefClient client, String url, boolean isTransparent, CefRequestContext context) { - if (isOffscreenRendered) return new CefBrowserOsr(client, url, isTransparent, context); - return new CefBrowserWr(client, url, context); + return new CefBrowserOsr(client, url, isTransparent, context); } } diff --git a/java/org/cef/browser/CefBrowserOsr.java b/java/org/cef/browser/CefBrowserOsr.java index 224fd119..99c276e4 100644 --- a/java/org/cef/browser/CefBrowserOsr.java +++ b/java/org/cef/browser/CefBrowserOsr.java @@ -124,9 +124,9 @@ private void createBrowserIfRequired(boolean hasParent) { if (getNativeRef("CefBrowser") == 0) { if (getParentBrowser() != null) { createDevTools(getParentBrowser(), getClient(), windowHandle, true, isTransparent_, - null, getInspectAt()); + getInspectAt()); } else { - createBrowser(getClient(), windowHandle, getUrl(), true, isTransparent_, null, + createBrowser(getClient(), windowHandle, getUrl(), true, isTransparent_, getRequestContext()); } } else if (hasParent && justCreated_) { diff --git a/java/org/cef/browser/CefBrowserWr.java b/java/org/cef/browser/CefBrowserWr.java deleted file mode 100644 index 583c4f41..00000000 --- a/java/org/cef/browser/CefBrowserWr.java +++ /dev/null @@ -1,424 +0,0 @@ -// Copyright (c) 2014 The Chromium Embedded Framework Authors. All rights -// reserved. Use of this source code is governed by a BSD-style license that -// can be found in the LICENSE file. - -package org.cef.browser; - -import org.cef.CefClient; -import org.cef.OS; -import org.cef.handler.CefWindowHandler; -import org.cef.handler.CefWindowHandlerAdapter; - -import java.awt.BorderLayout; -import java.awt.Canvas; -import java.awt.Component; -import java.awt.Container; -import java.awt.Dimension; -import java.awt.Graphics; -import java.awt.Graphics2D; -import java.awt.MouseInfo; -import java.awt.Point; -import java.awt.Rectangle; -import java.awt.Toolkit; -import java.awt.Window; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.awt.event.FocusEvent; -import java.awt.event.FocusListener; -import java.awt.event.HierarchyBoundsListener; -import java.awt.event.HierarchyEvent; -import java.awt.event.HierarchyListener; -import java.awt.event.MouseEvent; -import java.awt.event.MouseWheelEvent; -import java.awt.image.BufferedImage; -import java.util.Date; -import java.util.concurrent.CompletableFuture; - -import javax.swing.JPanel; -import javax.swing.JPopupMenu; -import javax.swing.MenuSelectionManager; -import javax.swing.SwingUtilities; -import javax.swing.Timer; -import javax.swing.ToolTipManager; - -/** - * This class represents a windowed rendered browser. - * The visibility of this class is "package". To create a new - * CefBrowser instance, please use CefBrowserFactory. - */ -class CefBrowserWr extends CefBrowser_N { - private Canvas canvas_ = null; - private Component component_ = null; - private Rectangle content_rect_ = new Rectangle(0, 0, 0, 0); - private long window_handle_ = 0; - private boolean justCreated_ = false; - private double scaleFactor_ = 1.0; - private Timer delayedUpdate_ = new Timer(100, new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - SwingUtilities.invokeLater(new Runnable() { - @Override - public void run() { - if (isClosed()) return; - - boolean hasCreatedUI = createBrowserIfRequired(true); - - if (hasCreatedUI) { - delayedUpdate_.restart(); - } else { - // If on Mac, this is needed due to the quirk described below - // (in org.cef.browser.CefBrowserWr.CefBrowserWr(...).new JPanel() - // {...}.paint(Graphics)). If on Linux, this is needed to invoke an - // XMoveResizeWindow call shortly after the UI was created. That seems to be - // necessary to actually get a windowed renderer to display something. - if (OS.isMacintosh() || OS.isLinux()) doUpdate(); - } - } - }); - } - }); - - private CefWindowHandlerAdapter win_handler_ = new CefWindowHandlerAdapter() { - private Point lastPos = new Point(-1, -1); - private long[] nextClick = new long[MouseInfo.getNumberOfButtons()]; - private int[] clickCnt = new int[MouseInfo.getNumberOfButtons()]; - - @Override - public Rectangle getRect(CefBrowser browser) { - synchronized (content_rect_) { - return content_rect_; - } - } - - @Override - public void onMouseEvent(CefBrowser browser, int event, final int screenX, - final int screenY, final int modifier, final int button) { - final Point pt = new Point(screenX, screenY); - if (event == MouseEvent.MOUSE_MOVED) { - // Remove mouse-moved events if the position of the cursor hasn't - // changed. - if (pt.equals(lastPos)) return; - lastPos = pt; - - // Change mouse-moved event to mouse-dragged event if the left mouse - // button is pressed. - if ((modifier & MouseEvent.BUTTON1_DOWN_MASK) != 0) - event = MouseEvent.MOUSE_DRAGGED; - } - - final int finalEvent = event; - - SwingUtilities.invokeLater(new Runnable() { - @Override - public void run() { - // Send mouse event to the root UI component instead to the browser UI. - // Otherwise no mouse-entered and no mouse-exited events would be fired. - Component parent = SwingUtilities.getRoot(component_); - if (parent == null) { - return; - } - SwingUtilities.convertPointFromScreen(pt, parent); - - int clickCnt = 0; - long now = new Date().getTime(); - if (finalEvent == MouseEvent.MOUSE_WHEEL) { - int scrollType = MouseWheelEvent.WHEEL_UNIT_SCROLL; - int rotation = button > 0 ? 1 : -1; - component_.dispatchEvent(new MouseWheelEvent(parent, finalEvent, now, - modifier, pt.x, pt.y, 0, false, scrollType, 3, rotation)); - } else { - clickCnt = getClickCount(finalEvent, button); - component_.dispatchEvent(new MouseEvent(parent, finalEvent, now, modifier, - pt.x, pt.y, screenX, screenY, clickCnt, false, button)); - } - - // Always fire a mouse-clicked event after a mouse-released event. - if (finalEvent == MouseEvent.MOUSE_RELEASED) { - component_.dispatchEvent( - new MouseEvent(parent, MouseEvent.MOUSE_CLICKED, now, modifier, - pt.x, pt.y, screenX, screenY, clickCnt, false, button)); - } - } - }); - } - - public int getClickCount(int event, int button) { - // avoid exceptions by using modulo - int idx = button % nextClick.length; - - switch (event) { - case MouseEvent.MOUSE_PRESSED: - long currTime = new Date().getTime(); - if (currTime > nextClick[idx]) { - nextClick[idx] = currTime - + (Integer) Toolkit.getDefaultToolkit().getDesktopProperty( - "awt.multiClickInterval"); - clickCnt[idx] = 1; - } else { - clickCnt[idx]++; - } - // FALL THRU - case MouseEvent.MOUSE_RELEASED: - return clickCnt[idx]; - default: - return 0; - } - } - }; - - CefBrowserWr(CefClient client, String url, CefRequestContext context) { - this(client, url, context, null, null); - } - - @SuppressWarnings("serial") - private CefBrowserWr(CefClient client, String url, CefRequestContext context, - CefBrowserWr parent, Point inspectAt) { - super(client, url, context, parent, inspectAt); - delayedUpdate_.setRepeats(false); - - // Disabling lightweight of popup menu is required because - // otherwise it will be displayed behind the content of component_ - JPopupMenu.setDefaultLightWeightPopupEnabled(false); - ToolTipManager.sharedInstance().setLightWeightPopupEnabled(false); - - // We're using a JComponent instead of a Canvas now because the - // JComponent has clipping informations, which aren't accessible for Canvas. - component_ = new JPanel(new BorderLayout()) { - private boolean removed_ = true; - - @Override - public void setBounds(int x, int y, int width, int height) { - super.setBounds(x, y, width, height); - wasResized((int) (width * scaleFactor_), (int) (height * scaleFactor_)); - } - - @Override - public void setBounds(Rectangle r) { - setBounds(r.x, r.y, r.width, r.height); - } - - @Override - public void setSize(int width, int height) { - super.setSize(width, height); - wasResized((int) (width * scaleFactor_), (int) (height * scaleFactor_)); - } - - @Override - public void setSize(Dimension d) { - setSize(d.width, d.height); - } - - @Override - public void paint(Graphics g) { - // If the user resizes the UI component, the new size and clipping - // informations are forwarded to the native code. - // But on Mac the last resize information doesn't resize the native UI - // accurately (sometimes the native UI is too small). An easy way to - // solve this, is to send the last Update-Information again. Therefore - // we're setting up a delayedUpdate timer which is reset each time - // paint is called. This prevents the us of sending the UI update too - // often. - if (g instanceof Graphics2D) { - scaleFactor_ = ((Graphics2D) g).getTransform().getScaleX(); - } - doUpdate(); - delayedUpdate_.restart(); - } - - @Override - public void addNotify() { - super.addNotify(); - if (removed_) { - setParent(getWindowHandle(this), canvas_); - removed_ = false; - } - } - - @Override - public void removeNotify() { - if (!removed_) { - if (!isClosed()) { - setParent(0, null); - } - removed_ = true; - } - super.removeNotify(); - } - }; - - // On windows we have to use a Canvas because its a heavyweight component - // and we need its native HWND as parent for the browser UI. The same - // technique is used on Linux as well. - if (OS.isWindows() || OS.isLinux()) { - canvas_ = new Canvas(); - ((JPanel) component_).add(canvas_, BorderLayout.CENTER); - } - - // Initial minimal size of the component. Otherwise the UI won't work - // accordingly in panes like JSplitPane. - component_.setMinimumSize(new Dimension(0, 0)); - component_.setFocusable(true); - component_.addFocusListener(new FocusListener() { - @Override - public void focusLost(FocusEvent e) { - setFocus(false); - } - - @Override - public void focusGained(FocusEvent e) { - // Dismiss any Java menus that are currently displayed. - MenuSelectionManager.defaultManager().clearSelectedPath(); - setFocus(true); - } - }); - component_.addHierarchyBoundsListener(new HierarchyBoundsListener() { - @Override - public void ancestorResized(HierarchyEvent e) { - doUpdate(); - } - @Override - public void ancestorMoved(HierarchyEvent e) { - doUpdate(); - notifyMoveOrResizeStarted(); - } - }); - component_.addHierarchyListener(new HierarchyListener() { - @Override - public void hierarchyChanged(HierarchyEvent e) { - if ((e.getChangeFlags() & HierarchyEvent.SHOWING_CHANGED) != 0) { - setWindowVisibility(e.getChanged().isVisible()); - } - } - }); - } - - @Override - public void createImmediately() { - justCreated_ = true; - SwingUtilities.invokeLater(new Runnable() { - @Override - public void run() { - // Create the browser immediately. It will be parented to the Java - // window once it becomes available. - createBrowserIfRequired(false); - } - }); - } - - @Override - public Component getUIComponent() { - return component_; - } - - @Override - public CefWindowHandler getWindowHandler() { - return win_handler_; - } - - @Override - protected CefBrowser_N createDevToolsBrowser(CefClient client, String url, - CefRequestContext context, CefBrowser_N parent, Point inspectAt) { - return new CefBrowserWr(client, url, context, (CefBrowserWr) this, inspectAt); - } - - private synchronized long getWindowHandle() { - if (window_handle_ == 0 && OS.isMacintosh()) { - window_handle_ = getWindowHandle(component_); - } - return window_handle_; - } - - private static long getWindowHandle(Component component) { - if (OS.isMacintosh()) { - try { - Class cls = Class.forName("org.cef.browser.mac.CefBrowserWindowMac"); - CefBrowserWindow browserWindow = (CefBrowserWindow) cls.newInstance(); - if (browserWindow != null) { - return browserWindow.getWindowHandle(component); - } - } catch (ClassNotFoundException e) { - e.printStackTrace(); - } catch (InstantiationException e) { - e.printStackTrace(); - } catch (IllegalAccessException e) { - e.printStackTrace(); - } - } - return 0; - } - - private void doUpdate() { - if (isClosed()) return; - - Rectangle vr = ((JPanel) component_).getVisibleRect(); - Rectangle clipping = new Rectangle((int) (vr.getX() * scaleFactor_), - (int) (vr.getY() * scaleFactor_), (int) (vr.getWidth() * scaleFactor_), - (int) (vr.getHeight() * scaleFactor_)); - - if (OS.isMacintosh()) { - Container parent = component_.getParent(); - Point contentPos = component_.getLocation(); - while (parent != null) { - Container next = parent.getParent(); - if (next != null && next instanceof Window) break; - Point parentPos = parent.getLocation(); - contentPos.translate(parentPos.x, parentPos.y); - parent = next; - } - contentPos.translate(clipping.x, clipping.y); - - Point browserPos = clipping.getLocation(); - browserPos.x *= -1; - browserPos.y *= -1; - - synchronized (content_rect_) { - content_rect_ = new Rectangle(contentPos, clipping.getSize()); - Rectangle browserRect = new Rectangle(browserPos, component_.getSize()); - updateUI(content_rect_, browserRect); - } - } else { - synchronized (content_rect_) { - Rectangle bounds = null != canvas_ ? canvas_.getBounds() : component_.getBounds(); - content_rect_ = new Rectangle((int) (bounds.getX() * scaleFactor_), - (int) (bounds.getY() * scaleFactor_), - (int) (bounds.getWidth() * scaleFactor_), - (int) (bounds.getHeight() * scaleFactor_)); - updateUI(clipping, content_rect_); - } - } - } - - private boolean createBrowserIfRequired(boolean hasParent) { - if (isClosed()) return false; - - long windowHandle = 0; - Component canvas = null; - if (hasParent) { - windowHandle = getWindowHandle(); - canvas = (OS.isWindows() || OS.isLinux()) ? canvas_ : component_; - } - - if (getNativeRef("CefBrowser") == 0) { - if (getParentBrowser() != null) { - createDevTools(getParentBrowser(), getClient(), windowHandle, false, false, canvas, - getInspectAt()); - return true; - } else { - createBrowser(getClient(), windowHandle, getUrl(), false, false, canvas, - getRequestContext()); - return true; - } - } else if (hasParent && justCreated_) { - setParent(windowHandle, canvas); - setFocus(true); - justCreated_ = false; - } - - return false; - } - - @Override - public CompletableFuture createScreenshot(boolean nativeResolution) { - throw new UnsupportedOperationException("Unsupported for windowed rendering"); - } -} diff --git a/java/org/cef/browser/CefBrowser_N.java b/java/org/cef/browser/CefBrowser_N.java index f3ad8f9f..d641098b 100644 --- a/java/org/cef/browser/CefBrowser_N.java +++ b/java/org/cef/browser/CefBrowser_N.java @@ -151,11 +151,11 @@ protected abstract CefBrowser_N createDevToolsBrowser(CefClient client, String u * Create a new browser. */ protected void createBrowser(CefClientHandler clientHandler, long windowHandle, String url, - boolean osr, boolean transparent, Component canvas, CefRequestContext context) { + boolean osr, boolean transparent, CefRequestContext context) { if (getNativeRef("CefBrowser") == 0 && !isPending_) { try { N_CreateBrowser( - clientHandler, windowHandle, url, osr, transparent, canvas, context); + clientHandler, windowHandle, url, osr, transparent, context); } catch (UnsatisfiedLinkError err) { err.printStackTrace(); } @@ -173,12 +173,12 @@ private void notifyBrowserCreated() { * Create a new browser as dev tools */ protected final void createDevTools(CefBrowser_N parent, CefClientHandler clientHandler, - long windowHandle, boolean osr, boolean transparent, Component canvas, + long windowHandle, boolean osr, boolean transparent, Point inspectAt) { if (getNativeRef("CefBrowser") == 0 && !isPending_) { try { isPending_ = N_CreateDevTools( - parent, clientHandler, windowHandle, osr, transparent, canvas, inspectAt); + parent, clientHandler, windowHandle, osr, transparent, inspectAt); } catch (UnsatisfiedLinkError err) { err.printStackTrace(); } @@ -728,16 +728,6 @@ protected final void updateUI(Rectangle contentRect, Rectangle browserRect) { } } - protected final void setParent(long windowHandle, Component canvas) { - if (isClosing_ || isClosed_) return; - - try { - N_SetParent(windowHandle, canvas); - } catch (UnsatisfiedLinkError ule) { - ule.printStackTrace(); - } - } - /** * Call this method if the browser frame was moved. * This fixes positioning of select popups and dismissal on window move/resize. @@ -751,10 +741,10 @@ protected final void notifyMoveOrResizeStarted() { } private final native boolean N_CreateBrowser(CefClientHandler clientHandler, long windowHandle, - String url, boolean osr, boolean transparent, Component canvas, + String url, boolean osr, boolean transparent, CefRequestContext context); private final native boolean N_CreateDevTools(CefBrowser parent, CefClientHandler clientHandler, - long windowHandle, boolean osr, boolean transparent, Component canvas, Point inspectAt); + long windowHandle, boolean osr, boolean transparent, Point inspectAt); private final native long N_GetWindowHandle(long surfaceHandle); private final native boolean N_CanGoBack(); private final native void N_GoBack(); @@ -811,6 +801,5 @@ private final native void N_DragTargetDragEnter( private final native void N_DragSourceEndedAt(Point pos, int operation); private final native void N_DragSourceSystemDragEnded(); private final native void N_UpdateUI(Rectangle contentRect, Rectangle browserRect); - private final native void N_SetParent(long windowHandle, Component canvas); private final native void N_NotifyMoveOrResizeStarted(); } From 5df32403712ab571fac90c690ea8d59a6a9f4c34 Mon Sep 17 00:00:00 2001 From: GiantLuigi4 <49770992+GiantLuigi4@users.noreply.github.com> Date: Tue, 8 Aug 2023 20:59:25 -0400 Subject: [PATCH 31/75] finish glfw migration completely(?) --- java/org/cef/CefClient.java | 101 ++++++++---------------------------- native/CefBrowser_N.cpp | 40 +++----------- 2 files changed, 29 insertions(+), 112 deletions(-) diff --git a/java/org/cef/CefClient.java b/java/org/cef/CefClient.java index 48a34134..ace0c5cc 100644 --- a/java/org/cef/CefClient.java +++ b/java/org/cef/CefClient.java @@ -47,11 +47,7 @@ import org.cef.network.CefResponse; import org.cef.network.CefURLRequest; -import java.awt.Component; -import java.awt.Container; import java.awt.Dimension; -import java.awt.FocusTraversalPolicy; -import java.awt.KeyboardFocusManager; import java.awt.Point; import java.awt.Rectangle; import java.beans.PropertyChangeEvent; @@ -68,9 +64,9 @@ */ public class CefClient extends CefClientHandler implements CefContextMenuHandler, CefDialogHandler, CefDisplayHandler, CefDownloadHandler, - CefDragHandler, CefFocusHandler, CefJSDialogHandler, CefKeyboardHandler, - CefLifeSpanHandler, CefLoadHandler, CefPrintHandler, CefRenderHandler, - CefRequestHandler, CefWindowHandler { + CefDragHandler, CefFocusHandler, CefJSDialogHandler, CefKeyboardHandler, + CefLifeSpanHandler, CefLoadHandler, CefPrintHandler, CefRenderHandler, + CefRequestHandler, CefWindowHandler { private HashMap browser_ = new HashMap(); private CefContextMenuHandler contextMenuHandler_ = null; private CefDialogHandler dialogHandler_ = null; @@ -85,43 +81,15 @@ public class CefClient extends CefClientHandler private CefPrintHandler printHandler_ = null; private CefRequestHandler requestHandler_ = null; private boolean isDisposed_ = false; - private volatile CefBrowser focusedBrowser_ = null; - private final PropertyChangeListener propertyChangeListener = new PropertyChangeListener() { - @Override - public void propertyChange(PropertyChangeEvent evt) { - if (focusedBrowser_ != null) { - Component browserUI = focusedBrowser_.getUIComponent(); - Object oldUI = evt.getOldValue(); - if (isPartOf(oldUI, browserUI)) { - focusedBrowser_.setFocus(false); - focusedBrowser_ = null; - } - } - } - }; /** * The CTOR is only accessible within this package. * Use CefApp.createClient() to create an instance of * this class. - * @see org.cef.CefApp.createClient() + * @see org.cef.CefApp#createClient() */ CefClient() throws UnsatisfiedLinkError { super(); - - KeyboardFocusManager.getCurrentKeyboardFocusManager().addPropertyChangeListener( - propertyChangeListener); - } - - private boolean isPartOf(Object obj, Component browserUI) { - if (obj == browserUI) return true; - if (obj instanceof Container) { - Component childs[] = ((Container) obj).getComponents(); - for (Component child : childs) { - return isPartOf(child, browserUI); - } - } - return false; } @Override @@ -133,15 +101,15 @@ public void dispose() { // CefClientHandler public CefBrowser createBrowser( - String url, boolean isOffscreenRendered, boolean isTransparent) { - return createBrowser(url, isOffscreenRendered, isTransparent, null); + String url, boolean isTransparent) { + return createBrowser(url, isTransparent, null); } - public CefBrowser createBrowser(String url, boolean isOffscreenRendered, boolean isTransparent, - CefRequestContext context) { + public CefBrowser createBrowser(String url, boolean isTransparent, + CefRequestContext context) { if (isDisposed_) throw new IllegalStateException("Can't create browser. CefClient is disposed"); - return CefBrowserFactory.create(this, url, isOffscreenRendered, isTransparent, context); + return CefBrowserFactory.create(this, url, isTransparent, context); } @Override @@ -248,7 +216,7 @@ public void onBeforeContextMenu( @Override public boolean onContextMenuCommand(CefBrowser browser, CefFrame frame, - CefContextMenuParams params, int commandId, int eventFlags) { + CefContextMenuParams params, int commandId, int eventFlags) { if (contextMenuHandler_ != null && browser != null) return contextMenuHandler_.onContextMenuCommand( browser, frame, params, commandId, eventFlags); @@ -274,7 +242,7 @@ public void removeDialogHandler() { @Override public boolean onFileDialog(CefBrowser browser, FileDialogMode mode, String title, - String defaultFilePath, Vector acceptFilters, CefFileDialogCallback callback) { + String defaultFilePath, Vector acceptFilters, CefFileDialogCallback callback) { if (dialogHandler_ != null && browser != null) { return dialogHandler_.onFileDialog( browser, mode, title, defaultFilePath, acceptFilters, callback); @@ -322,7 +290,7 @@ public void onStatusMessage(CefBrowser browser, String value) { @Override public boolean onConsoleMessage(CefBrowser browser, CefSettings.LogSeverity level, - String message, String source, int line) { + String message, String source, int line) { if (displayHandler_ != null && browser != null) { return displayHandler_.onConsoleMessage(browser, level, message, source, line); } @@ -360,7 +328,7 @@ public void removeDownloadHandler() { @Override public void onBeforeDownload(CefBrowser browser, CefDownloadItem downloadItem, - String suggestedName, CefBeforeDownloadCallback callback) { + String suggestedName, CefBeforeDownloadCallback callback) { if (downloadHandler_ != null && browser != null) downloadHandler_.onBeforeDownload(browser, downloadItem, suggestedName, callback); } @@ -406,26 +374,6 @@ public void onTakeFocus(CefBrowser browser, boolean next) { if (browser == null) return; browser.setFocus(false); - Container parent = browser.getUIComponent().getParent(); - if (parent != null) { - FocusTraversalPolicy policy = null; - while (parent != null) { - policy = parent.getFocusTraversalPolicy(); - if (policy != null) break; - parent = parent.getParent(); - } - if (policy != null) { - Component nextComp = next - ? policy.getComponentAfter(parent, browser.getUIComponent()) - : policy.getComponentBefore(parent, browser.getUIComponent()); - if (nextComp == null) { - policy.getDefaultComponent(parent).requestFocus(); - } else { - nextComp.requestFocus(); - } - } - } - focusedBrowser_ = null; if (focusHandler_ != null) focusHandler_.onTakeFocus(browser, next); } @@ -442,7 +390,6 @@ public boolean onSetFocus(final CefBrowser browser, FocusSource source) { public void onGotFocus(CefBrowser browser) { if (browser == null) return; - focusedBrowser_ = browser; browser.setFocus(true); if (focusHandler_ != null) focusHandler_.onGotFocus(browser); } @@ -460,8 +407,8 @@ public void removeJSDialogHandler() { @Override public boolean onJSDialog(CefBrowser browser, String origin_url, JSDialogType dialog_type, - String message_text, String default_prompt_text, CefJSDialogCallback callback, - BoolRef suppress_message) { + String message_text, String default_prompt_text, CefJSDialogCallback callback, + BoolRef suppress_message) { if (jsDialogHandler_ != null && browser != null) return jsDialogHandler_.onJSDialog(browser, origin_url, dialog_type, message_text, default_prompt_text, callback, suppress_message); @@ -470,7 +417,7 @@ public boolean onJSDialog(CefBrowser browser, String origin_url, JSDialogType di @Override public boolean onBeforeUnloadDialog(CefBrowser browser, String message_text, boolean is_reload, - CefJSDialogCallback callback) { + CefJSDialogCallback callback) { if (jsDialogHandler_ != null && browser != null) return jsDialogHandler_.onBeforeUnloadDialog( browser, message_text, is_reload, callback); @@ -584,8 +531,6 @@ private void cleanupBrowser(int identifier) { } if (browser_.isEmpty() && isDisposed_) { - KeyboardFocusManager.getCurrentKeyboardFocusManager().removePropertyChangeListener( - propertyChangeListener); removeContextMenuHandler(this); removeDialogHandler(this); removeDisplayHandler(this); @@ -639,7 +584,7 @@ public void onLoadEnd(CefBrowser browser, CefFrame frame, int httpStatusCode) { @Override public void onLoadError(CefBrowser browser, CefFrame frame, ErrorCode errorCode, - String errorText, String failedUrl) { + String errorText, String failedUrl) { if (loadHandler_ != null && browser != null) loadHandler_.onLoadError(browser, frame, errorCode, errorText, failedUrl); } @@ -677,7 +622,7 @@ public boolean onPrintDialog( @Override public boolean onPrintJob(CefBrowser browser, String documentName, String pdfFilePath, - CefPrintJobCallback callback) { + CefPrintJobCallback callback) { if (printHandler_ != null && browser != null) return printHandler_.onPrintJob(browser, documentName, pdfFilePath, callback); return false; @@ -745,7 +690,7 @@ public void onPopupSize(CefBrowser browser, Rectangle size) { @Override public void onPaint(CefBrowser browser, boolean popup, Rectangle[] dirtyRects, - ByteBuffer buffer, int width, int height) { + ByteBuffer buffer, int width, int height) { if (browser == null) return; CefRenderHandler realHandler = browser.getRenderHandler(); @@ -783,7 +728,7 @@ public void removeRequestHandler() { @Override public boolean onBeforeBrowse(CefBrowser browser, CefFrame frame, CefRequest request, - boolean user_gesture, boolean is_redirect) { + boolean user_gesture, boolean is_redirect) { if (requestHandler_ != null && browser != null) return requestHandler_.onBeforeBrowse( browser, frame, request, user_gesture, is_redirect); @@ -801,8 +746,8 @@ public boolean onOpenURLFromTab( @Override public CefResourceRequestHandler getResourceRequestHandler(CefBrowser browser, CefFrame frame, - CefRequest request, boolean isNavigation, boolean isDownload, String requestInitiator, - BoolRef disableDefaultHandling) { + CefRequest request, boolean isNavigation, boolean isDownload, String requestInitiator, + BoolRef disableDefaultHandling) { if (requestHandler_ != null && browser != null) { return requestHandler_.getResourceRequestHandler(browser, frame, request, isNavigation, isDownload, requestInitiator, disableDefaultHandling); @@ -812,7 +757,7 @@ public CefResourceRequestHandler getResourceRequestHandler(CefBrowser browser, C @Override public boolean getAuthCredentials(CefBrowser browser, String origin_url, boolean isProxy, - String host, int port, String realm, String scheme, CefAuthCallback callback) { + String host, int port, String realm, String scheme, CefAuthCallback callback) { if (requestHandler_ != null && browser != null) return requestHandler_.getAuthCredentials( browser, origin_url, isProxy, host, port, realm, scheme, callback); diff --git a/native/CefBrowser_N.cpp b/native/CefBrowser_N.cpp index 583107af..5a3028ce 100644 --- a/native/CefBrowser_N.cpp +++ b/native/CefBrowser_N.cpp @@ -40,34 +40,6 @@ namespace { -int GetCefModifiers(JNIEnv* env, jclass cls, int modifiers) { - JNI_STATIC_DEFINE_INT_RV(env, cls, ALT_DOWN_MASK, 0); - JNI_STATIC_DEFINE_INT_RV(env, cls, BUTTON1_DOWN_MASK, 0); - JNI_STATIC_DEFINE_INT_RV(env, cls, BUTTON2_DOWN_MASK, 0); - JNI_STATIC_DEFINE_INT_RV(env, cls, BUTTON3_DOWN_MASK, 0); - JNI_STATIC_DEFINE_INT_RV(env, cls, CTRL_DOWN_MASK, 0); - JNI_STATIC_DEFINE_INT_RV(env, cls, META_DOWN_MASK, 0); - JNI_STATIC_DEFINE_INT_RV(env, cls, SHIFT_DOWN_MASK, 0); - - int cef_modifiers = 0; - if (modifiers & JNI_STATIC(ALT_DOWN_MASK)) - cef_modifiers |= EVENTFLAG_ALT_DOWN; - if (modifiers & JNI_STATIC(BUTTON1_DOWN_MASK)) - cef_modifiers |= EVENTFLAG_LEFT_MOUSE_BUTTON; - if (modifiers & JNI_STATIC(BUTTON2_DOWN_MASK)) - cef_modifiers |= EVENTFLAG_MIDDLE_MOUSE_BUTTON; - if (modifiers & JNI_STATIC(BUTTON3_DOWN_MASK)) - cef_modifiers |= EVENTFLAG_RIGHT_MOUSE_BUTTON; - if (modifiers & JNI_STATIC(CTRL_DOWN_MASK)) - cef_modifiers |= EVENTFLAG_CONTROL_DOWN; - if (modifiers & JNI_STATIC(META_DOWN_MASK)) - cef_modifiers |= EVENTFLAG_COMMAND_DOWN; - if (modifiers & JNI_STATIC(SHIFT_DOWN_MASK)) - cef_modifiers |= EVENTFLAG_SHIFT_DOWN; - - return cef_modifiers; -} - int GetCefModifiersGlfw(JNIEnv* env, jclass cls, int modifiers) { JNI_STATIC_DEFINE_INT_RV(env, cls, GLFW_MOD_ALT, 0); JNI_STATIC_DEFINE_INT_RV(env, cls, GLFW_MOD_CONTROL, 0); @@ -1912,13 +1884,13 @@ Java_org_cef_browser_CefBrowser_1N_N_1DragTargetDragEnter(JNIEnv* env, GetCefFromJNIObject(env, jdragData, "CefDragData"); if (!drag_data.get()) return; - ScopedJNIClass cls(env, "java/awt/event/MouseEvent"); + ScopedJNIClass cls(env, "org/lwjgl/glfw/GLFW"); if (!cls) return; CefMouseEvent cef_event; GetJNIPoint(env, pos, &cef_event.x, &cef_event.y); - cef_event.modifiers = GetCefModifiers(env, cls, jmodifiers); + cef_event.modifiers = GetCefModifiersGlfw(env, cls, jmodifiers); CefRefPtr browser = JNI_GET_BROWSER_OR_RETURN(env, obj); browser->GetHost()->DragTargetDragEnter( @@ -1931,13 +1903,13 @@ Java_org_cef_browser_CefBrowser_1N_N_1DragTargetDragOver(JNIEnv* env, jobject pos, jint jmodifiers, jint allowedOps) { - ScopedJNIClass cls(env, "java/awt/event/MouseEvent"); + ScopedJNIClass cls(env, "org/lwjgl/glfw/GLFW"); if (!cls) return; CefMouseEvent cef_event; GetJNIPoint(env, pos, &cef_event.x, &cef_event.y); - cef_event.modifiers = GetCefModifiers(env, cls, jmodifiers); + cef_event.modifiers = GetCefModifiersGlfw(env, cls, jmodifiers); CefRefPtr browser = JNI_GET_BROWSER_OR_RETURN(env, obj); browser->GetHost()->DragTargetDragOver( @@ -1956,13 +1928,13 @@ Java_org_cef_browser_CefBrowser_1N_N_1DragTargetDrop(JNIEnv* env, jobject obj, jobject pos, jint jmodifiers) { - ScopedJNIClass cls(env, "java/awt/event/MouseEvent"); + ScopedJNIClass cls(env, "org/lwjgl/glfw/GLFW"); if (!cls) return; CefMouseEvent cef_event; GetJNIPoint(env, pos, &cef_event.x, &cef_event.y); - cef_event.modifiers = GetCefModifiers(env, cls, jmodifiers); + cef_event.modifiers = GetCefModifiersGlfw(env, cls, jmodifiers); CefRefPtr browser = JNI_GET_BROWSER_OR_RETURN(env, obj); browser->GetHost()->DragTargetDrop(cef_event); From dcb414442879f7a733dd1845350a97826fa80d42 Mon Sep 17 00:00:00 2001 From: GiantLuigi4 <49770992+GiantLuigi4@users.noreply.github.com> Date: Tue, 8 Aug 2023 21:50:16 -0400 Subject: [PATCH 32/75] don't map mouse types, but I'm gonna wanna make a java enum for that eventually --- native/display_handler.cpp | 73 +------------------------------------- 1 file changed, 1 insertion(+), 72 deletions(-) diff --git a/native/display_handler.cpp b/native/display_handler.cpp index cf088682..60874291 100644 --- a/native/display_handler.cpp +++ b/native/display_handler.cpp @@ -6,77 +6,6 @@ #include "jni_util.h" -namespace { - -int GetCursorId(cef_cursor_type_t type) { - ScopedJNIEnv env; - if (!env) - return 0; - - const char* cursorClassName = "java/awt/Cursor"; - JNI_STATIC_DEFINE_INT_RV(env, ScopedJNIClass(env, cursorClassName), - CROSSHAIR_CURSOR, 0); - JNI_STATIC_DEFINE_INT_RV(env, ScopedJNIClass(env, cursorClassName), - DEFAULT_CURSOR, 0); - JNI_STATIC_DEFINE_INT_RV(env, ScopedJNIClass(env, cursorClassName), - E_RESIZE_CURSOR, 0); - JNI_STATIC_DEFINE_INT_RV(env, ScopedJNIClass(env, cursorClassName), - HAND_CURSOR, 0); - JNI_STATIC_DEFINE_INT_RV(env, ScopedJNIClass(env, cursorClassName), - MOVE_CURSOR, 0); - JNI_STATIC_DEFINE_INT_RV(env, ScopedJNIClass(env, cursorClassName), - N_RESIZE_CURSOR, 0); - JNI_STATIC_DEFINE_INT_RV(env, ScopedJNIClass(env, cursorClassName), - NE_RESIZE_CURSOR, 0); - JNI_STATIC_DEFINE_INT_RV(env, ScopedJNIClass(env, cursorClassName), - NW_RESIZE_CURSOR, 0); - JNI_STATIC_DEFINE_INT_RV(env, ScopedJNIClass(env, cursorClassName), - S_RESIZE_CURSOR, 0); - JNI_STATIC_DEFINE_INT_RV(env, ScopedJNIClass(env, cursorClassName), - SE_RESIZE_CURSOR, 0); - JNI_STATIC_DEFINE_INT_RV(env, ScopedJNIClass(env, cursorClassName), - SW_RESIZE_CURSOR, 0); - JNI_STATIC_DEFINE_INT_RV(env, ScopedJNIClass(env, cursorClassName), - TEXT_CURSOR, 0); - JNI_STATIC_DEFINE_INT_RV(env, ScopedJNIClass(env, cursorClassName), - W_RESIZE_CURSOR, 0); - JNI_STATIC_DEFINE_INT_RV(env, ScopedJNIClass(env, cursorClassName), - WAIT_CURSOR, 0); - - switch (type) { - case CT_CROSS: - return JNI_STATIC(CROSSHAIR_CURSOR); - case CT_HAND: - return JNI_STATIC(HAND_CURSOR); - case CT_IBEAM: - return JNI_STATIC(TEXT_CURSOR); - case CT_WAIT: - return JNI_STATIC(WAIT_CURSOR); - case CT_EASTRESIZE: - return JNI_STATIC(E_RESIZE_CURSOR); - case CT_NORTHRESIZE: - return JNI_STATIC(N_RESIZE_CURSOR); - case CT_NORTHEASTRESIZE: - return JNI_STATIC(NE_RESIZE_CURSOR); - case CT_NORTHWESTRESIZE: - return JNI_STATIC(NW_RESIZE_CURSOR); - case CT_SOUTHRESIZE: - return JNI_STATIC(S_RESIZE_CURSOR); - case CT_SOUTHEASTRESIZE: - return JNI_STATIC(SE_RESIZE_CURSOR); - case CT_SOUTHWESTRESIZE: - return JNI_STATIC(SW_RESIZE_CURSOR); - case CT_WESTRESIZE: - return JNI_STATIC(W_RESIZE_CURSOR); - case CT_MOVE: - return JNI_STATIC(MOVE_CURSOR); - default: - return JNI_STATIC(DEFAULT_CURSOR); - } -} - -} // namespace - DisplayHandler::DisplayHandler(JNIEnv* env, jobject handler) : handle_(env, handler) {} @@ -191,7 +120,7 @@ bool DisplayHandler::OnCursorChange(CefRefPtr browser, return false; ScopedJNIBrowser jbrowser(env, browser); - const int cursorId = GetCursorId(type); + const int cursorId = (int) type; jboolean jreturn = JNI_FALSE; JNI_CALL_METHOD(env, handle_, "onCursorChange", From d3b560755abbcdb792952c107878d578f9556c00 Mon Sep 17 00:00:00 2001 From: GiantLuigi4 <49770992+GiantLuigi4@users.noreply.github.com> Date: Wed, 9 Aug 2023 16:23:50 -0400 Subject: [PATCH 33/75] cursor types --- java/org/cef/misc/CefCursorType.java | 59 ++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 java/org/cef/misc/CefCursorType.java diff --git a/java/org/cef/misc/CefCursorType.java b/java/org/cef/misc/CefCursorType.java new file mode 100644 index 00000000..0f6178d4 --- /dev/null +++ b/java/org/cef/misc/CefCursorType.java @@ -0,0 +1,59 @@ +package org.cef.misc; + +public enum CefCursorType { + POINTER(0), + CROSS(0x36003), // GLFW_CROSSHAIR_CURSOR + HAND(0x36004), // GLFW_HAND_CURSOR + IBEAM(0x36002), // GLFW_IBEAM_CURSOR + WAIT(0), + HELP(0), + EAST_RESIZE(0x36005), // GLFW_RESIZE_EW_CURSOR + NORTH_RESIZE(0x36006), // GLFW_RESIZE_NS_CURSOR + NORTH_EAST_RESIZE(0x36008), // GLFW_RESIZE_NESW_CURSOR + NORTH_WEST_RESIZE(0x36007), // GLFW_RESIZE_NWSE_CURSOR + SOUTH_RESIZE(0x36006), // GLFW_RESIZE_NS_CURSOR + SOUTH_EAST_RESIZE(0x36007), // GLFW_RESIZE_NWSE_CURSOR + SOUTH_WEST_RESIZE(0x36008), // GLFW_RESIZE_NESW_CURSOR + WEST_RESIZE(0x36005), // GLFW_RESIZE_EW_CURSOR + NORTH_SOUTH_RESIZE(0x36006), // GLFW_RESIZE_NS_CURSOR + EAST_WEST_RESIZE(0x36005), // GLFW_RESIZE_EW_CURSOR + NORTH_EAST_SOUTH_WEST_RESIZE(0x36008), // GLFW_RESIZE_NESW_CURSOR + NORTH_WEST_SOUTH_EAST_RESIZE(0x36007), // GLFW_RESIZE_NWSE_CURSOR + COLUMN_RESIZE(0), + ROW_RESIZE(0), + MIDDLE_PANNING(0), + EAST_PANNING(0), + NORTH_PANNING(0), + NORTH_EAST_PANNING(0), + NORTH_WEST_PANNING(0), + SOUTH_PANNING(0), + SOUTH_EAST_PANNING(0), + SOUTH_WEST_PANNING(0), + WEST_PANNING(0), + MOVE(0x36009), // GLFW_RESIZE_ALL_CURSOR + VERTICAL_IBEAM(0), // VERTICAL_TEXT + CELL(0), + CONTEXT_MENU(0), + ALIAS(0), + PROGRESS(0), + NO_DROP(0x3600A), // GLFW_NOT_ALLOWED_CURSOR + COPY(0), + NONE(0), + NOT_ALLOWED(0x3600A), // GLFW_NOT_ALLOWED_CURSOR + ZOOM_IN(0), + ZOOM_OUT(0), + GRAB(0), + GRABBING(0), + CUSTOM(0), + ; + + int glfwId; + + CefCursorType(int glfwId) { + this.glfwId = glfwId; + } + + public static CefCursorType fromId(int id) { + return values()[id]; + } +} From bb11155b03d62d9b258e84593cbcdbd7b5b8d77d Mon Sep 17 00:00:00 2001 From: GiantLuigi4 <49770992+GiantLuigi4@users.noreply.github.com> Date: Wed, 9 Aug 2023 16:25:16 -0400 Subject: [PATCH 34/75] remove some setFocus calls from CefClient, as they cause errors --- java/org/cef/CefClient.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/java/org/cef/CefClient.java b/java/org/cef/CefClient.java index ace0c5cc..50880cd4 100644 --- a/java/org/cef/CefClient.java +++ b/java/org/cef/CefClient.java @@ -373,7 +373,6 @@ public void removeFocusHandler() { public void onTakeFocus(CefBrowser browser, boolean next) { if (browser == null) return; - browser.setFocus(false); if (focusHandler_ != null) focusHandler_.onTakeFocus(browser, next); } @@ -390,7 +389,6 @@ public boolean onSetFocus(final CefBrowser browser, FocusSource source) { public void onGotFocus(CefBrowser browser) { if (browser == null) return; - browser.setFocus(true); if (focusHandler_ != null) focusHandler_.onGotFocus(browser); } From 0ad5c3847c52efad71a6c8fdb3de9540251cda4d Mon Sep 17 00:00:00 2001 From: GiantLuigi4 <49770992+GiantLuigi4@users.noreply.github.com> Date: Wed, 9 Aug 2023 16:35:30 -0400 Subject: [PATCH 35/75] I always forget access modifiers on enum fields and methods --- java/org/cef/misc/CefCursorType.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/org/cef/misc/CefCursorType.java b/java/org/cef/misc/CefCursorType.java index 0f6178d4..a014cc91 100644 --- a/java/org/cef/misc/CefCursorType.java +++ b/java/org/cef/misc/CefCursorType.java @@ -47,7 +47,7 @@ public enum CefCursorType { CUSTOM(0), ; - int glfwId; + public final int glfwId; CefCursorType(int glfwId) { this.glfwId = glfwId; From f1aa06df10defe8feec848383643cac8f4f4da53 Mon Sep 17 00:00:00 2001 From: ds58 <30220598+ds58@users.noreply.github.com> Date: Wed, 9 Aug 2023 18:41:57 -0500 Subject: [PATCH 36/75] Load jawt in CefApp if on Linux --- java/org/cef/CefApp.java | 1 + 1 file changed, 1 insertion(+) diff --git a/java/org/cef/CefApp.java b/java/org/cef/CefApp.java index 9469205a..6868d416 100644 --- a/java/org/cef/CefApp.java +++ b/java/org/cef/CefApp.java @@ -455,6 +455,7 @@ public static final boolean startup(String[] args) { System.load(jcefPath + "/libjcef.dylib"); return N_Startup(getCefFrameworkPath(args)); } else if (OS.isLinux()) { + System.loadLibrary("jawt"); System.load(jcefPath + "/libcef.so"); System.load(jcefPath + "/libjcef.so"); return N_Startup(null); From 7c00f03fbf6eda67020751b1f88bafa6838c89a5 Mon Sep 17 00:00:00 2001 From: GiantLuigi4 <49770992+GiantLuigi4@users.noreply.github.com> Date: Wed, 9 Aug 2023 20:42:28 -0400 Subject: [PATCH 37/75] hopefully this stops linking against awt? --- native/jni_util.cpp | 1 - native/jni_util_linux.cpp | 48 ------------------------------------- native/jni_util_win.cpp | 50 --------------------------------------- 3 files changed, 99 deletions(-) diff --git a/native/jni_util.cpp b/native/jni_util.cpp index d88f750f..27c104d9 100644 --- a/native/jni_util.cpp +++ b/native/jni_util.cpp @@ -4,7 +4,6 @@ #include "jni_util.h" -#include #include #include "jni_scoped_helpers.h" diff --git a/native/jni_util_linux.cpp b/native/jni_util_linux.cpp index acd28e1d..9ec2489e 100644 --- a/native/jni_util_linux.cpp +++ b/native/jni_util_linux.cpp @@ -3,51 +3,3 @@ // can be found in the LICENSE file. #include "jni_util.h" - -#include -#include -#include - -unsigned long GetDrawableOfCanvas(jobject canvas, JNIEnv* env) { - JAWT awt; - JAWT_DrawingSurface* ds; - JAWT_DrawingSurfaceInfo* dsi; - JAWT_X11DrawingSurfaceInfo* dsi_x11; - jint lock; - - // Get the AWT. - awt.version = JAWT_VERSION_1_4; - JAWT_GetAWT(env, &awt); - - // Get the drawing surface. - ds = awt.GetDrawingSurface(env, canvas); - assert(ds != nullptr); - - // Lock the drawing surface. - // May fail during shutdown. - lock = ds->Lock(ds); - if (lock & JAWT_LOCK_ERROR) { - return 0; - } - - // Get the drawing surface info. - dsi = ds->GetDrawingSurfaceInfo(ds); - if (dsi == nullptr) { - // Unlock the drawing surface - ds->Unlock(ds); - return 0; - } - - // Get the platform-specific drawing info. - dsi_x11 = (JAWT_X11DrawingSurfaceInfo*)dsi->platformInfo; - Drawable result = dsi_x11->drawable; - - // Free the drawing surface info - ds->FreeDrawingSurfaceInfo(dsi); - // Unlock the drawing surface - ds->Unlock(ds); - // Free the drawing surface - awt.FreeDrawingSurface(ds); - - return result; -} diff --git a/native/jni_util_win.cpp b/native/jni_util_win.cpp index a1fa5729..9ec2489e 100644 --- a/native/jni_util_win.cpp +++ b/native/jni_util_win.cpp @@ -3,53 +3,3 @@ // can be found in the LICENSE file. #include "jni_util.h" - -#include -#include -#include - -HWND GetHwndOfCanvas(jobject canvas, JNIEnv* env) { - JAWT awt; - JAWT_DrawingSurface* ds; - JAWT_DrawingSurfaceInfo* dsi; - JAWT_Win32DrawingSurfaceInfo* dsi_win; - jboolean bGetAwt; - jint lock; - - // Get the AWT. - awt.version = JAWT_VERSION_1_4; - bGetAwt = JAWT_GetAWT(env, &awt); - assert(bGetAwt != JNI_FALSE); - - // Get the drawing surface. - ds = awt.GetDrawingSurface(env, canvas); - assert(ds != nullptr); - - // Lock the drawing surface. - // May fail during shutdown. - lock = ds->Lock(ds); - if (lock & JAWT_LOCK_ERROR) { - return 0; - } - - // Get the drawing surface info. - dsi = ds->GetDrawingSurfaceInfo(ds); - if (dsi == nullptr) { - // Unlock the drawing surface - ds->Unlock(ds); - return 0; - } - - // Get the platform-specific drawing info. - dsi_win = (JAWT_Win32DrawingSurfaceInfo*)dsi->platformInfo; - HWND result = dsi_win->hwnd; - - // Free the drawing surface info - ds->FreeDrawingSurfaceInfo(dsi); - // Unlock the drawing surface - ds->Unlock(ds); - // Free the drawing surface - awt.FreeDrawingSurface(ds); - - return result; -} From 7b2416f1c5ea61ceb36d81b8951947f0463ff164 Mon Sep 17 00:00:00 2001 From: ds58 <30220598+ds58@users.noreply.github.com> Date: Wed, 9 Aug 2023 20:32:35 -0500 Subject: [PATCH 38/75] Revert "Load jawt in CefApp if on Linux" This reverts commit f1aa06df10defe8feec848383643cac8f4f4da53. --- java/org/cef/CefApp.java | 1 - 1 file changed, 1 deletion(-) diff --git a/java/org/cef/CefApp.java b/java/org/cef/CefApp.java index 6868d416..9469205a 100644 --- a/java/org/cef/CefApp.java +++ b/java/org/cef/CefApp.java @@ -455,7 +455,6 @@ public static final boolean startup(String[] args) { System.load(jcefPath + "/libjcef.dylib"); return N_Startup(getCefFrameworkPath(args)); } else if (OS.isLinux()) { - System.loadLibrary("jawt"); System.load(jcefPath + "/libcef.so"); System.load(jcefPath + "/libjcef.so"); return N_Startup(null); From 8a273dcc61fd28cf8bc9159ef3a726f2d4ad91f6 Mon Sep 17 00:00:00 2001 From: ds58 <30220598+ds58@users.noreply.github.com> Date: Wed, 9 Aug 2023 23:42:15 -0500 Subject: [PATCH 39/75] Make broken tests at least compile --- java/tests/detailed/MainFrame.java | 2 +- java/tests/junittests/TestFrame.java | 2 +- java/tests/simple/MainFrame.java | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/java/tests/detailed/MainFrame.java b/java/tests/detailed/MainFrame.java index f13b321d..ea2d720c 100644 --- a/java/tests/detailed/MainFrame.java +++ b/java/tests/detailed/MainFrame.java @@ -202,7 +202,7 @@ public void onLoadError(CefBrowser browser, CefFrame frame, ErrorCode errorCode, // Create the browser. CefBrowser browser = client_.createBrowser( - "http://www.google.com", osrEnabled, transparentPaintingEnabled, null); + "http://www.google.com", osrEnabled, null); setBrowser(browser); // Set up the UI for this example implementation. diff --git a/java/tests/junittests/TestFrame.java b/java/tests/junittests/TestFrame.java index 78742d6b..78151ba4 100644 --- a/java/tests/junittests/TestFrame.java +++ b/java/tests/junittests/TestFrame.java @@ -105,7 +105,7 @@ public void windowClosing(WindowEvent e) { protected void createBrowser(String startURL) { assertNull(browser_); - browser_ = client_.createBrowser(startURL, false /* useOSR */, false /* isTransparent */); + browser_ = client_.createBrowser(startURL, false /* isTransparent */); assertNotNull(browser_); getContentPane().add(browser_.getUIComponent(), BorderLayout.CENTER); diff --git a/java/tests/simple/MainFrame.java b/java/tests/simple/MainFrame.java index 7b2b21ab..9d68fd1c 100644 --- a/java/tests/simple/MainFrame.java +++ b/java/tests/simple/MainFrame.java @@ -104,7 +104,7 @@ public void stateHasChanged(org.cef.CefApp.CefAppState state) { // by calling the method "getUIComponent()" on the instance of CefBrowser. // The UI component is inherited from a java.awt.Component and therefore // it can be embedded into any AWT UI. - browser_ = client_.createBrowser(startURL, useOSR, isTransparent); + browser_ = client_.createBrowser(startURL, isTransparent); browerUI_ = browser_.getUIComponent(); // (4) For this minimal browser, we need only a text field to enter an URL From 58d940893e60487a3576f61e70e13f3a5183f476 Mon Sep 17 00:00:00 2001 From: ds58 <30220598+ds58@users.noreply.github.com> Date: Wed, 9 Aug 2023 23:50:32 -0500 Subject: [PATCH 40/75] Use new mcef-downloads to download CEF. Fix compile issue on macOS --- cmake/DownloadCEF.cmake | 2 +- native/CefBrowser_N.cpp | 36 +++++++++++++++++++----------------- 2 files changed, 20 insertions(+), 18 deletions(-) diff --git a/cmake/DownloadCEF.cmake b/cmake/DownloadCEF.cmake index d7967a19..b2d11930 100644 --- a/cmake/DownloadCEF.cmake +++ b/cmake/DownloadCEF.cmake @@ -21,7 +21,7 @@ function(DownloadCEF platform branch version download_dir) set(CEF_DOWNLOAD_FILENAME "${CEF_DISTRIBUTION}.tar.bz2") set(CEF_DOWNLOAD_PATH "${CEF_DOWNLOAD_DIR}/${CEF_DOWNLOAD_FILENAME}") if(NOT EXISTS "${CEF_DOWNLOAD_PATH}") - set(CEF_DOWNLOAD_URL "https://ewr1.vultrobjects.com/cef-builds/${branch}/${CEF_DOWNLOAD_FILENAME}") + set(CEF_DOWNLOAD_URL "https://mcef-download.cinemamod.com/cef-builds/${branch}/${CEF_DOWNLOAD_FILENAME}") string(REPLACE "+" "%2B" CEF_DOWNLOAD_URL_ESCAPED ${CEF_DOWNLOAD_URL}) # Download the SHA1 hash for the binary distribution. diff --git a/native/CefBrowser_N.cpp b/native/CefBrowser_N.cpp index 5a3028ce..bef1da00 100644 --- a/native/CefBrowser_N.cpp +++ b/native/CefBrowser_N.cpp @@ -994,23 +994,25 @@ void getZoomLevel(CefRefPtr host, } } -void OnAfterParentChanged(CefRefPtr browser) { - if (!CefCurrentlyOn(TID_UI)) { - CefPostTask(TID_UI, base::BindOnce(&OnAfterParentChanged, browser)); - return; - } - - if (browser->GetHost()->GetClient()) { - CefRefPtr lifeSpanHandler = - (LifeSpanHandler*)browser->GetHost() - ->GetClient() - ->GetLifeSpanHandler() - .get(); - if (lifeSpanHandler) { - lifeSpanHandler->OnAfterParentChanged(browser); - } - } -} +// Removed because we don't care about when the native parent window changes. +// This fixes a compile issue on macOS - ds58 +//void OnAfterParentChanged(CefRefPtr browser) { +// if (!CefCurrentlyOn(TID_UI)) { +// CefPostTask(TID_UI, base::BindOnce(&OnAfterParentChanged, browser)); +// return; +// } +// +// if (browser->GetHost()->GetClient()) { +// CefRefPtr lifeSpanHandler = +// (LifeSpanHandler*)browser->GetHost() +// ->GetClient() +// ->GetLifeSpanHandler() +// .get(); +// if (lifeSpanHandler) { +// lifeSpanHandler->OnAfterParentChanged(browser); +// } +// } +//} jobject NewJNILongVector(JNIEnv* env, const std::vector& vals) { ScopedJNIObjectLocal jvector(env, "java/util/Vector"); From bd9372c5cab8ac8780228e97c1b5558932e7f95c Mon Sep 17 00:00:00 2001 From: ds58 <30220598+ds58@users.noreply.github.com> Date: Thu, 10 Aug 2023 11:46:35 -0500 Subject: [PATCH 41/75] Add the ability to run a custom shutdown after a macOS termination event request --- java/org/cef/CefApp.java | 42 +++++++++++++++++----------------------- 1 file changed, 18 insertions(+), 24 deletions(-) diff --git a/java/org/cef/CefApp.java b/java/org/cef/CefApp.java index 9469205a..eff69e01 100644 --- a/java/org/cef/CefApp.java +++ b/java/org/cef/CefApp.java @@ -387,42 +387,36 @@ private final void initialize() { if (N_Initialize(appHandler_, settings)) setState(CefAppState.INITIALIZED); } + /** + * CEF takes full control of Cmd+Q and doesn't allow our application to see that it has been pressed. + * This allows us to run our application's shutdown code, so we can have a graceful "Cmd+Q" exit. + */ + public Runnable macOSTerminationRequestRunnable = new Runnable() { + @Override + public void run() { + } + }; + /** * This method is invoked by the native code (currently on Mac only) in case * of a termination event (e.g. someone pressed CMD+Q). */ protected final void handleBeforeTerminate() { - System.out.println("Cmd+Q termination request."); - // Execute on the AWT event dispatching thread. Always call asynchronously - // so the call stack has a chance to unwind. - SwingUtilities.invokeLater(new Runnable() { - @Override - public void run() { - CefAppHandler handler = - (CefAppHandler) ((appHandler_ == null) ? this : appHandler_); - if (!handler.onBeforeTerminate()) dispose(); - } - }); +// CefAppHandler handler = +// (CefAppHandler) ((appHandler_ == null) ? this : appHandler_); +// if (!handler.onBeforeTerminate()) dispose(); + macOSTerminationRequestRunnable.run(); } /** * Shut down the context. */ private final void shutdown() { - // Execute on the AWT event dispatching thread. Always call asynchronously - // so the call stack has a chance to unwind. - SwingUtilities.invokeLater(new Runnable() { - @Override - public void run() { - System.out.println("shutdown on " + Thread.currentThread()); + // Shutdown native CEF. + N_Shutdown(); - // Shutdown native CEF. - N_Shutdown(); - - setState(CefAppState.TERMINATED); - CefApp.self = null; - } - }); + setState(CefAppState.TERMINATED); + CefApp.self = null; } /** From c742c4e0c5d41d80e469cb8ae2d16510465e1a77 Mon Sep 17 00:00:00 2001 From: ds58 <30220598+ds58@users.noreply.github.com> Date: Thu, 10 Aug 2023 13:37:31 -0500 Subject: [PATCH 42/75] Revert "Cmake find JNI" This reverts commit 5f131499ec0a2268fb149fcbf847b8d05427a6e5. --- CMakeLists.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6454cf7e..e887a171 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -216,6 +216,9 @@ set(JAVA_FATAL_ERROR "A Java installation is required. Set the JAVA_HOME " "installation directory.") # Find the Java Native Interface (JNI) installation. +set(JAVA_INCLUDE_PATH NotNeeded) +set(JAVA_INCLUDE_PATH2 NotNeeded) +set(JAVA_AWT_INCLUDE_PATH NotNeeded) find_package(JNI ${JDK_MIN_VERSION}) if(NOT ${JNI_FOUND}) message(FATAL_ERROR ${JAVA_FATAL_ERROR}) From 564afc52d7a1f1a05844e2ac75ff4baff221a722 Mon Sep 17 00:00:00 2001 From: ds58 <30220598+ds58@users.noreply.github.com> Date: Fri, 11 Aug 2023 13:37:17 -0500 Subject: [PATCH 43/75] Github workflow, fix windows compile --- .github/workflows/build-jcef.yml | 133 +++++++++++++++++++++++++++++++ CMakeLists.txt | 6 +- native/util_win.cpp | 2 +- 3 files changed, 137 insertions(+), 4 deletions(-) create mode 100644 .github/workflows/build-jcef.yml diff --git a/.github/workflows/build-jcef.yml b/.github/workflows/build-jcef.yml new file mode 100644 index 00000000..53d248eb --- /dev/null +++ b/.github/workflows/build-jcef.yml @@ -0,0 +1,133 @@ +name: Build java-cef 5359 + +on: [workflow_dispatch] + +jobs: + java-cef-linux-amd64: + runs-on: [ubuntu-20.04] + steps: + - uses: actions/checkout@v3 + - run: | + ls -al + sudo apt update + sudo apt install build-essential g++ cmake ninja-build openjdk-17-jdk python3 libgtk2.0-dev -y + mkdir jcef_build && cd jcef_build + export JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64 + export JAVA_INCLUDE_PATH=/usr/lib/jvm/java-17-openjdk-amd64/include + cmake -G "Ninja" -DPROJECT_ARCH=amd64 -DCMAKE_BUILD_TYPE=Release .. + ninja -j4 + mv native/Release native/linux_amd64 + strip native/linux_amd64/libcef.so + tar -czf linux_amd64.tar.gz -C native . + ls -al + pwd + - name: Upload artifact + uses: actions/upload-artifact@v3 + with: + name: linux-amd64 + path: /home/runner/work/java-cef/java-cef/jcef_build/linux_amd64.tar.gz + java-cef-linux-arm64: + runs-on: [ubuntu-20.04] + steps: + - uses: actions/checkout@v3 + - run: | + ls -al + sudo apt update + sudo apt install build-essential g++ cmake ninja-build openjdk-17-jdk python3 libgtk2.0-dev -y + mkdir jcef_build && cd jcef_build + export JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64 + export JAVA_INCLUDE_PATH=/usr/lib/jvm/java-17-openjdk-amd64/include + cmake -G "Ninja" -DPROJECT_ARCH=arm64 -DCMAKE_BUILD_TYPE=Release .. + ninja -j4 + mv native/Release native/linux_arm64 + strip native/linux_arm64/libcef.so + tar -czf linux_arm64.tar.gz -C native . + ls -al + pwd + - name: Upload artifact + uses: actions/upload-artifact@v3 + with: + name: linux-arm64 + path: /home/runner/work/java-cef/java-cef/jcef_build/linux_arm64.tar.gz + java-cef-windows-amd64: + runs-on: [windows-2022] + steps: + - uses: actions/checkout@v3 + - uses: ilammy/msvc-dev-cmd@v1 + - run: | + dir + mkdir jcef_build && cd jcef_build + cmake -G "Ninja" -DPROJECT_ARCH=amd64 -DCMAKE_BUILD_TYPE=Release .. + ninja -j4 + cd native + ren Release windows_amd64 + cd .. + tar -czf windows_amd64.tar.gz -C native . + dir + cd + - name: Upload artifact + uses: actions/upload-artifact@v3 + with: + name: windows-amd64 + path: D:\a\java-cef\java-cef\jcef_build\windows_amd64.tar.gz + java-cef-windows-arm64: + runs-on: [windows-2022] + steps: + - uses: actions/checkout@v3 + - uses: ilammy/msvc-dev-cmd@v1 + - run: | + dir + mkdir jcef_build && cd jcef_build + cmake -G "Ninja" -DPROJECT_ARCH=arm64 -DCMAKE_BUILD_TYPE=Release .. + ninja -j4 + cd native + ren Release windows_arm64 + cd .. + tar -czf windows_arm64.tar.gz -C native . + dir + cd + - name: Upload artifact + uses: actions/upload-artifact@v3 + with: + name: windows-arm64 + path: D:\a\java-cef\java-cef\jcef_build\windows_arm64.tar.gz + java-cef-macos-amd64: + runs-on: [macos-12] + steps: + - uses: actions/checkout@v3 + - run: | + ls -al + brew install ninja + sudo xcode-select --switch /Applications/Xcode_13.1.app + mkdir jcef_build && cd jcef_build + cmake -G "Ninja" -DPROJECT_ARCH=amd64 -DCMAKE_BUILD_TYPE=Release .. + ninja -j4 + mv native/Release native/macos_amd64 + tar -czf macos_amd64.tar.gz -C native . + ls -al + pwd + - name: Upload artifact + uses: actions/upload-artifact@v3 + with: + name: macos-amd64 + path: /Users/runner/work/java-cef/java-cef/jcef_build/macos_amd64.tar.gz + java-cef-macos-arm64: + runs-on: [macos-12] + steps: + - uses: actions/checkout@v3 + - run: | + ls -al + brew install ninja + sudo xcode-select --switch /Applications/Xcode_13.1.app + mkdir jcef_build && cd jcef_build + cmake -G "Ninja" -DPROJECT_ARCH=arm64 -DCMAKE_BUILD_TYPE=Release .. + ninja -j4 + mv native/Release native/macos_arm + tar -czf macos_arm64.tar.gz -C native . + ls -al + pwd + - name: Upload artifact + uses: actions/upload-artifact@v3 + with: + name: macos-arm64 + path: /Users/runner/work/java-cef/java-cef/jcef_build/macos_arm64.tar.gz diff --git a/CMakeLists.txt b/CMakeLists.txt index e887a171..b5c6dbad 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -117,6 +117,8 @@ cmake_minimum_required(VERSION 3.19) # Only generate Debug and Release configuration types. set(CMAKE_CONFIGURATION_TYPES Debug Release) +set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded") + # Project name. project(jcef) @@ -216,9 +218,7 @@ set(JAVA_FATAL_ERROR "A Java installation is required. Set the JAVA_HOME " "installation directory.") # Find the Java Native Interface (JNI) installation. -set(JAVA_INCLUDE_PATH NotNeeded) -set(JAVA_INCLUDE_PATH2 NotNeeded) -set(JAVA_AWT_INCLUDE_PATH NotNeeded) + find_package(JNI ${JDK_MIN_VERSION}) if(NOT ${JNI_FOUND}) message(FATAL_ERROR ${JAVA_FATAL_ERROR}) diff --git a/native/util_win.cpp b/native/util_win.cpp index cd60ef7d..2bfc53e3 100644 --- a/native/util_win.cpp +++ b/native/util_win.cpp @@ -307,7 +307,7 @@ void DestroyCefBrowser(CefRefPtr browser) { } CefWindowHandle GetWindowHandle(JNIEnv* env, jobject canvas) { - return GetHwndOfCanvas(canvas, env); + return 0; } void SetParent(CefWindowHandle browserHandle, From 9e4d28a31482f436bc071cb6014e772204da2d8e Mon Sep 17 00:00:00 2001 From: ds58 <30220598+ds58@users.noreply.github.com> Date: Fri, 11 Aug 2023 22:54:43 -0500 Subject: [PATCH 44/75] Remove workflow --- .github/workflows/build-jcef.yml | 133 ------------------------------- 1 file changed, 133 deletions(-) delete mode 100644 .github/workflows/build-jcef.yml diff --git a/.github/workflows/build-jcef.yml b/.github/workflows/build-jcef.yml deleted file mode 100644 index 53d248eb..00000000 --- a/.github/workflows/build-jcef.yml +++ /dev/null @@ -1,133 +0,0 @@ -name: Build java-cef 5359 - -on: [workflow_dispatch] - -jobs: - java-cef-linux-amd64: - runs-on: [ubuntu-20.04] - steps: - - uses: actions/checkout@v3 - - run: | - ls -al - sudo apt update - sudo apt install build-essential g++ cmake ninja-build openjdk-17-jdk python3 libgtk2.0-dev -y - mkdir jcef_build && cd jcef_build - export JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64 - export JAVA_INCLUDE_PATH=/usr/lib/jvm/java-17-openjdk-amd64/include - cmake -G "Ninja" -DPROJECT_ARCH=amd64 -DCMAKE_BUILD_TYPE=Release .. - ninja -j4 - mv native/Release native/linux_amd64 - strip native/linux_amd64/libcef.so - tar -czf linux_amd64.tar.gz -C native . - ls -al - pwd - - name: Upload artifact - uses: actions/upload-artifact@v3 - with: - name: linux-amd64 - path: /home/runner/work/java-cef/java-cef/jcef_build/linux_amd64.tar.gz - java-cef-linux-arm64: - runs-on: [ubuntu-20.04] - steps: - - uses: actions/checkout@v3 - - run: | - ls -al - sudo apt update - sudo apt install build-essential g++ cmake ninja-build openjdk-17-jdk python3 libgtk2.0-dev -y - mkdir jcef_build && cd jcef_build - export JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64 - export JAVA_INCLUDE_PATH=/usr/lib/jvm/java-17-openjdk-amd64/include - cmake -G "Ninja" -DPROJECT_ARCH=arm64 -DCMAKE_BUILD_TYPE=Release .. - ninja -j4 - mv native/Release native/linux_arm64 - strip native/linux_arm64/libcef.so - tar -czf linux_arm64.tar.gz -C native . - ls -al - pwd - - name: Upload artifact - uses: actions/upload-artifact@v3 - with: - name: linux-arm64 - path: /home/runner/work/java-cef/java-cef/jcef_build/linux_arm64.tar.gz - java-cef-windows-amd64: - runs-on: [windows-2022] - steps: - - uses: actions/checkout@v3 - - uses: ilammy/msvc-dev-cmd@v1 - - run: | - dir - mkdir jcef_build && cd jcef_build - cmake -G "Ninja" -DPROJECT_ARCH=amd64 -DCMAKE_BUILD_TYPE=Release .. - ninja -j4 - cd native - ren Release windows_amd64 - cd .. - tar -czf windows_amd64.tar.gz -C native . - dir - cd - - name: Upload artifact - uses: actions/upload-artifact@v3 - with: - name: windows-amd64 - path: D:\a\java-cef\java-cef\jcef_build\windows_amd64.tar.gz - java-cef-windows-arm64: - runs-on: [windows-2022] - steps: - - uses: actions/checkout@v3 - - uses: ilammy/msvc-dev-cmd@v1 - - run: | - dir - mkdir jcef_build && cd jcef_build - cmake -G "Ninja" -DPROJECT_ARCH=arm64 -DCMAKE_BUILD_TYPE=Release .. - ninja -j4 - cd native - ren Release windows_arm64 - cd .. - tar -czf windows_arm64.tar.gz -C native . - dir - cd - - name: Upload artifact - uses: actions/upload-artifact@v3 - with: - name: windows-arm64 - path: D:\a\java-cef\java-cef\jcef_build\windows_arm64.tar.gz - java-cef-macos-amd64: - runs-on: [macos-12] - steps: - - uses: actions/checkout@v3 - - run: | - ls -al - brew install ninja - sudo xcode-select --switch /Applications/Xcode_13.1.app - mkdir jcef_build && cd jcef_build - cmake -G "Ninja" -DPROJECT_ARCH=amd64 -DCMAKE_BUILD_TYPE=Release .. - ninja -j4 - mv native/Release native/macos_amd64 - tar -czf macos_amd64.tar.gz -C native . - ls -al - pwd - - name: Upload artifact - uses: actions/upload-artifact@v3 - with: - name: macos-amd64 - path: /Users/runner/work/java-cef/java-cef/jcef_build/macos_amd64.tar.gz - java-cef-macos-arm64: - runs-on: [macos-12] - steps: - - uses: actions/checkout@v3 - - run: | - ls -al - brew install ninja - sudo xcode-select --switch /Applications/Xcode_13.1.app - mkdir jcef_build && cd jcef_build - cmake -G "Ninja" -DPROJECT_ARCH=arm64 -DCMAKE_BUILD_TYPE=Release .. - ninja -j4 - mv native/Release native/macos_arm - tar -czf macos_arm64.tar.gz -C native . - ls -al - pwd - - name: Upload artifact - uses: actions/upload-artifact@v3 - with: - name: macos-arm64 - path: /Users/runner/work/java-cef/java-cef/jcef_build/macos_arm64.tar.gz From 18e6289f9ce82af4439c73f3bbca273abe49f019 Mon Sep 17 00:00:00 2001 From: GiantLuigi4 <49770992+GiantLuigi4@users.noreply.github.com> Date: Sat, 12 Aug 2023 00:19:59 -0400 Subject: [PATCH 45/75] apply a change that was made to windows, but do it to linux also minor formatting on CMakeLists.txt --- CMakeLists.txt | 1 - native/util_linux.cpp | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b5c6dbad..f133b048 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -218,7 +218,6 @@ set(JAVA_FATAL_ERROR "A Java installation is required. Set the JAVA_HOME " "installation directory.") # Find the Java Native Interface (JNI) installation. - find_package(JNI ${JDK_MIN_VERSION}) if(NOT ${JNI_FOUND}) message(FATAL_ERROR ${JAVA_FATAL_ERROR}) diff --git a/native/util_linux.cpp b/native/util_linux.cpp index e04e9f88..52807be0 100644 --- a/native/util_linux.cpp +++ b/native/util_linux.cpp @@ -54,7 +54,7 @@ void DestroyCefBrowser(CefRefPtr browser) { } CefWindowHandle GetWindowHandle(JNIEnv* env, jobject canvas) { - return GetDrawableOfCanvas(canvas, env); + return 0; } void SetParent(CefWindowHandle browserHandle, From ab40fc01fb948d5d11c6fda3ef4a7ad7fc6baad6 Mon Sep 17 00:00:00 2001 From: ds58 <30220598+ds58@users.noreply.github.com> Date: Sat, 12 Aug 2023 13:28:30 -0500 Subject: [PATCH 46/75] Upload workflow artifacts to s3 --- .github/workflows/build-jcef.yml | 165 ++++++++++++------------------- 1 file changed, 61 insertions(+), 104 deletions(-) diff --git a/.github/workflows/build-jcef.yml b/.github/workflows/build-jcef.yml index 53d248eb..cbac33a5 100644 --- a/.github/workflows/build-jcef.yml +++ b/.github/workflows/build-jcef.yml @@ -3,131 +3,88 @@ name: Build java-cef 5359 on: [workflow_dispatch] jobs: - java-cef-linux-amd64: + java-cef-linux: runs-on: [ubuntu-20.04] + strategy: + matrix: + platform: [amd64, arm64] steps: + - name: Upload mask + run: echo "::add-mask::${{ secrets.UPLOAD_URL }}" - uses: actions/checkout@v3 - - run: | - ls -al - sudo apt update - sudo apt install build-essential g++ cmake ninja-build openjdk-17-jdk python3 libgtk2.0-dev -y - mkdir jcef_build && cd jcef_build - export JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64 - export JAVA_INCLUDE_PATH=/usr/lib/jvm/java-17-openjdk-amd64/include - cmake -G "Ninja" -DPROJECT_ARCH=amd64 -DCMAKE_BUILD_TYPE=Release .. - ninja -j4 - mv native/Release native/linux_amd64 - strip native/linux_amd64/libcef.so - tar -czf linux_amd64.tar.gz -C native . - ls -al - pwd - - name: Upload artifact - uses: actions/upload-artifact@v3 - with: - name: linux-amd64 - path: /home/runner/work/java-cef/java-cef/jcef_build/linux_amd64.tar.gz - java-cef-linux-arm64: - runs-on: [ubuntu-20.04] - steps: - - uses: actions/checkout@v3 - - run: | - ls -al + - name: Install deps and build + run: | sudo apt update - sudo apt install build-essential g++ cmake ninja-build openjdk-17-jdk python3 libgtk2.0-dev -y + sudo apt install build-essential g++ cmake ninja-build openjdk-17-jdk python3 libgtk2.0-dev s3cmd -y mkdir jcef_build && cd jcef_build export JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64 export JAVA_INCLUDE_PATH=/usr/lib/jvm/java-17-openjdk-amd64/include - cmake -G "Ninja" -DPROJECT_ARCH=arm64 -DCMAKE_BUILD_TYPE=Release .. - ninja -j4 - mv native/Release native/linux_arm64 - strip native/linux_arm64/libcef.so - tar -czf linux_arm64.tar.gz -C native . - ls -al - pwd - - name: Upload artifact - uses: actions/upload-artifact@v3 - with: - name: linux-arm64 - path: /home/runner/work/java-cef/java-cef/jcef_build/linux_arm64.tar.gz - java-cef-windows-amd64: - runs-on: [windows-2022] - steps: - - uses: actions/checkout@v3 - - uses: ilammy/msvc-dev-cmd@v1 - - run: | - dir - mkdir jcef_build && cd jcef_build - cmake -G "Ninja" -DPROJECT_ARCH=amd64 -DCMAKE_BUILD_TYPE=Release .. + cmake -G "Ninja" -DPROJECT_ARCH=${{ matrix.platform }} -DCMAKE_BUILD_TYPE=Release .. ninja -j4 - cd native - ren Release windows_amd64 - cd .. - tar -czf windows_amd64.tar.gz -C native . - dir - cd - - name: Upload artifact - uses: actions/upload-artifact@v3 - with: - name: windows-amd64 - path: D:\a\java-cef\java-cef\jcef_build\windows_amd64.tar.gz - java-cef-windows-arm64: + mv native/Release native/linux_${{ matrix.platform }} + strip native/linux_${{ matrix.platform }}/libcef.so + tar -czf linux_${{ matrix.platform }}.tar.gz -C native . + sha256sum linux_${{ matrix.platform }}.tar.gz > linux_${{ matrix.platform }}.tar.gz.sha256 + - name: Copy s3cfg + run: echo "${{ secrets.S3_CFG }}" > ~/.s3cfg + - name: Upload java-cef build + run: | + s3cmd put -P /home/runner/work/java-cef/java-cef/jcef_build/linux_${{ matrix.platform }}.tar.gz s3://mcef-us-1/java-cef-builds/${{ github.sha }}/linux_${{ matrix.platform }}.tar.gz + s3cmd put -P /home/runner/work/java-cef/java-cef/jcef_build/linux_${{ matrix.platform }}.tar.gz.sha256 s3://mcef-us-1/java-cef-builds/${{ github.sha }}/linux_${{ matrix.platform }}.tar.gz.sha256 + java-cef-windows: runs-on: [windows-2022] + strategy: + matrix: + platform: [amd64, arm64] steps: + - name: Upload mask + run: echo "::add-mask::${{ secrets.UPLOAD_URL }}" - uses: actions/checkout@v3 - uses: ilammy/msvc-dev-cmd@v1 - - run: | - dir + - name: Install s3cmd + run: | + pip install python-dateutil + Invoke-WebRequest -Uri "https://github.com/s3tools/s3cmd/archive/master.zip" -OutFile "D:\s3cmd.zip" + Expand-Archive -Path "D:\s3cmd.zip" -DestinationPath "D:\s3cmd" + - name: Build + run: | mkdir jcef_build && cd jcef_build - cmake -G "Ninja" -DPROJECT_ARCH=arm64 -DCMAKE_BUILD_TYPE=Release .. + cmake -G "Ninja" -DPROJECT_ARCH=${{ matrix.platform }} -DCMAKE_BUILD_TYPE=Release .. ninja -j4 cd native - ren Release windows_arm64 + ren Release windows_${{ matrix.platform }} cd .. - tar -czf windows_arm64.tar.gz -C native . - dir - cd - - name: Upload artifact - uses: actions/upload-artifact@v3 - with: - name: windows-arm64 - path: D:\a\java-cef\java-cef\jcef_build\windows_arm64.tar.gz - java-cef-macos-amd64: - runs-on: [macos-12] - steps: - - uses: actions/checkout@v3 - - run: | - ls -al - brew install ninja - sudo xcode-select --switch /Applications/Xcode_13.1.app - mkdir jcef_build && cd jcef_build - cmake -G "Ninja" -DPROJECT_ARCH=amd64 -DCMAKE_BUILD_TYPE=Release .. - ninja -j4 - mv native/Release native/macos_amd64 - tar -czf macos_amd64.tar.gz -C native . - ls -al - pwd - - name: Upload artifact - uses: actions/upload-artifact@v3 - with: - name: macos-amd64 - path: /Users/runner/work/java-cef/java-cef/jcef_build/macos_amd64.tar.gz - java-cef-macos-arm64: + tar -czf windows_${{ matrix.platform }}.tar.gz -C native . + Get-FileHash -Algorithm SHA256 -Path "windows_${{ matrix.platform }}.tar.gz" | Out-File "windows_${{ matrix.platform }}.tar.gz.sha256" + - name: Copy s3cfg + run: echo "${{ secrets.S3_CFG }}" > "$HOME\AppData\Roaming\s3cmd.ini" + - name: Upload java-cef build + run: | + python D:\s3cmd\s3cmd-master\s3cmd put -P D:\a\java-cef\java-cef\jcef_build\windows_${{ matrix.platform }}.tar.gz s3://mcef-us-1/java-cef-builds/${{ github.sha }}/windows_${{ matrix.platform }}.tar.gz + python D:\s3cmd\s3cmd-master\s3cmd put -P D:\a\java-cef\java-cef\jcef_build\windows_${{ matrix.platform }}.tar.gz.sha256 s3://mcef-us-1/java-cef-builds/${{ github.sha }}/windows_${{ matrix.platform }}.tar.gz.sha256 + java-cef-macos: runs-on: [macos-12] + strategy: + matrix: + platform: [amd64, arm64] steps: + - name: Upload mask + run: echo "::add-mask::${{ secrets.UPLOAD_URL }}" - uses: actions/checkout@v3 - run: | - ls -al brew install ninja + brew install coreutils + brew install s3cmd sudo xcode-select --switch /Applications/Xcode_13.1.app mkdir jcef_build && cd jcef_build - cmake -G "Ninja" -DPROJECT_ARCH=arm64 -DCMAKE_BUILD_TYPE=Release .. + cmake -G "Ninja" -DPROJECT_ARCH=${{ matrix.platform }} -DCMAKE_BUILD_TYPE=Release .. ninja -j4 - mv native/Release native/macos_arm - tar -czf macos_arm64.tar.gz -C native . - ls -al - pwd - - name: Upload artifact - uses: actions/upload-artifact@v3 - with: - name: macos-arm64 - path: /Users/runner/work/java-cef/java-cef/jcef_build/macos_arm64.tar.gz + mv native/Release native/macos_${{ matrix.platform }} + tar -czf macos_${{ matrix.platform }}.tar.gz -C native . + sha256sum macos_${{ matrix.platform }}.tar.gz > macos_${{ matrix.platform }}.tar.gz.sha256 + - name: Copy s3cfg + run: echo "${{ secrets.S3_CFG }}" > ~/.s3cfg + - name: Upload java-cef build + run: | + s3cmd put -P /Users/runner/work/java-cef/java-cef/jcef_build/macos_${{ matrix.platform }}.tar.gz s3://mcef-us-1/java-cef-builds/${{ github.sha }}/macos_${{ matrix.platform }}.tar.gz + s3cmd put -P /Users/runner/work/java-cef/java-cef/jcef_build/macos_${{ matrix.platform }}.tar.gz.sha256 s3://mcef-us-1/java-cef-builds/${{ github.sha }}/macos_${{ matrix.platform }}.tar.gz.sha256 From 70ae22cdaa7dc8cef50eb45537898375259a1093 Mon Sep 17 00:00:00 2001 From: ds58 <30220598+ds58@users.noreply.github.com> Date: Sat, 12 Aug 2023 13:28:30 -0500 Subject: [PATCH 47/75] Upload workflow artifacts to s3 --- .github/workflows/build-jcef.yml | 90 ++++++++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 .github/workflows/build-jcef.yml diff --git a/.github/workflows/build-jcef.yml b/.github/workflows/build-jcef.yml new file mode 100644 index 00000000..cbac33a5 --- /dev/null +++ b/.github/workflows/build-jcef.yml @@ -0,0 +1,90 @@ +name: Build java-cef 5359 + +on: [workflow_dispatch] + +jobs: + java-cef-linux: + runs-on: [ubuntu-20.04] + strategy: + matrix: + platform: [amd64, arm64] + steps: + - name: Upload mask + run: echo "::add-mask::${{ secrets.UPLOAD_URL }}" + - uses: actions/checkout@v3 + - name: Install deps and build + run: | + sudo apt update + sudo apt install build-essential g++ cmake ninja-build openjdk-17-jdk python3 libgtk2.0-dev s3cmd -y + mkdir jcef_build && cd jcef_build + export JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64 + export JAVA_INCLUDE_PATH=/usr/lib/jvm/java-17-openjdk-amd64/include + cmake -G "Ninja" -DPROJECT_ARCH=${{ matrix.platform }} -DCMAKE_BUILD_TYPE=Release .. + ninja -j4 + mv native/Release native/linux_${{ matrix.platform }} + strip native/linux_${{ matrix.platform }}/libcef.so + tar -czf linux_${{ matrix.platform }}.tar.gz -C native . + sha256sum linux_${{ matrix.platform }}.tar.gz > linux_${{ matrix.platform }}.tar.gz.sha256 + - name: Copy s3cfg + run: echo "${{ secrets.S3_CFG }}" > ~/.s3cfg + - name: Upload java-cef build + run: | + s3cmd put -P /home/runner/work/java-cef/java-cef/jcef_build/linux_${{ matrix.platform }}.tar.gz s3://mcef-us-1/java-cef-builds/${{ github.sha }}/linux_${{ matrix.platform }}.tar.gz + s3cmd put -P /home/runner/work/java-cef/java-cef/jcef_build/linux_${{ matrix.platform }}.tar.gz.sha256 s3://mcef-us-1/java-cef-builds/${{ github.sha }}/linux_${{ matrix.platform }}.tar.gz.sha256 + java-cef-windows: + runs-on: [windows-2022] + strategy: + matrix: + platform: [amd64, arm64] + steps: + - name: Upload mask + run: echo "::add-mask::${{ secrets.UPLOAD_URL }}" + - uses: actions/checkout@v3 + - uses: ilammy/msvc-dev-cmd@v1 + - name: Install s3cmd + run: | + pip install python-dateutil + Invoke-WebRequest -Uri "https://github.com/s3tools/s3cmd/archive/master.zip" -OutFile "D:\s3cmd.zip" + Expand-Archive -Path "D:\s3cmd.zip" -DestinationPath "D:\s3cmd" + - name: Build + run: | + mkdir jcef_build && cd jcef_build + cmake -G "Ninja" -DPROJECT_ARCH=${{ matrix.platform }} -DCMAKE_BUILD_TYPE=Release .. + ninja -j4 + cd native + ren Release windows_${{ matrix.platform }} + cd .. + tar -czf windows_${{ matrix.platform }}.tar.gz -C native . + Get-FileHash -Algorithm SHA256 -Path "windows_${{ matrix.platform }}.tar.gz" | Out-File "windows_${{ matrix.platform }}.tar.gz.sha256" + - name: Copy s3cfg + run: echo "${{ secrets.S3_CFG }}" > "$HOME\AppData\Roaming\s3cmd.ini" + - name: Upload java-cef build + run: | + python D:\s3cmd\s3cmd-master\s3cmd put -P D:\a\java-cef\java-cef\jcef_build\windows_${{ matrix.platform }}.tar.gz s3://mcef-us-1/java-cef-builds/${{ github.sha }}/windows_${{ matrix.platform }}.tar.gz + python D:\s3cmd\s3cmd-master\s3cmd put -P D:\a\java-cef\java-cef\jcef_build\windows_${{ matrix.platform }}.tar.gz.sha256 s3://mcef-us-1/java-cef-builds/${{ github.sha }}/windows_${{ matrix.platform }}.tar.gz.sha256 + java-cef-macos: + runs-on: [macos-12] + strategy: + matrix: + platform: [amd64, arm64] + steps: + - name: Upload mask + run: echo "::add-mask::${{ secrets.UPLOAD_URL }}" + - uses: actions/checkout@v3 + - run: | + brew install ninja + brew install coreutils + brew install s3cmd + sudo xcode-select --switch /Applications/Xcode_13.1.app + mkdir jcef_build && cd jcef_build + cmake -G "Ninja" -DPROJECT_ARCH=${{ matrix.platform }} -DCMAKE_BUILD_TYPE=Release .. + ninja -j4 + mv native/Release native/macos_${{ matrix.platform }} + tar -czf macos_${{ matrix.platform }}.tar.gz -C native . + sha256sum macos_${{ matrix.platform }}.tar.gz > macos_${{ matrix.platform }}.tar.gz.sha256 + - name: Copy s3cfg + run: echo "${{ secrets.S3_CFG }}" > ~/.s3cfg + - name: Upload java-cef build + run: | + s3cmd put -P /Users/runner/work/java-cef/java-cef/jcef_build/macos_${{ matrix.platform }}.tar.gz s3://mcef-us-1/java-cef-builds/${{ github.sha }}/macos_${{ matrix.platform }}.tar.gz + s3cmd put -P /Users/runner/work/java-cef/java-cef/jcef_build/macos_${{ matrix.platform }}.tar.gz.sha256 s3://mcef-us-1/java-cef-builds/${{ github.sha }}/macos_${{ matrix.platform }}.tar.gz.sha256 From 53ffd2ef0ac22472177de9a836ba88457fde62c7 Mon Sep 17 00:00:00 2001 From: ds58 <30220598+ds58@users.noreply.github.com> Date: Sat, 12 Aug 2023 13:40:31 -0500 Subject: [PATCH 48/75] Change workflow events --- .github/workflows/build-jcef.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build-jcef.yml b/.github/workflows/build-jcef.yml index cbac33a5..31f9d83d 100644 --- a/.github/workflows/build-jcef.yml +++ b/.github/workflows/build-jcef.yml @@ -1,6 +1,10 @@ name: Build java-cef 5359 -on: [workflow_dispatch] +on: + push: + branches: + - master + workflow_dispatch: jobs: java-cef-linux: From 73cd8b12b63e6251a196526aaae9071593190104 Mon Sep 17 00:00:00 2001 From: ds58 <30220598+ds58@users.noreply.github.com> Date: Sat, 12 Aug 2023 14:38:29 -0500 Subject: [PATCH 49/75] Add pull_request to workflow events --- .github/workflows/build-jcef.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/build-jcef.yml b/.github/workflows/build-jcef.yml index 31f9d83d..d7de4647 100644 --- a/.github/workflows/build-jcef.yml +++ b/.github/workflows/build-jcef.yml @@ -4,6 +4,7 @@ on: push: branches: - master + pull_request: workflow_dispatch: jobs: From 173d0ac1e274e5392be0a2c4110daa22b58a554b Mon Sep 17 00:00:00 2001 From: ds58 <30220598+ds58@users.noreply.github.com> Date: Sat, 12 Aug 2023 17:50:03 -0500 Subject: [PATCH 50/75] Flatten build archives --- .github/workflows/build-jcef.yml | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build-jcef.yml b/.github/workflows/build-jcef.yml index d7de4647..20cead50 100644 --- a/.github/workflows/build-jcef.yml +++ b/.github/workflows/build-jcef.yml @@ -26,9 +26,9 @@ jobs: export JAVA_INCLUDE_PATH=/usr/lib/jvm/java-17-openjdk-amd64/include cmake -G "Ninja" -DPROJECT_ARCH=${{ matrix.platform }} -DCMAKE_BUILD_TYPE=Release .. ninja -j4 - mv native/Release native/linux_${{ matrix.platform }} - strip native/linux_${{ matrix.platform }}/libcef.so - tar -czf linux_${{ matrix.platform }}.tar.gz -C native . + mv native/Release linux_${{ matrix.platform }} + strip linux_${{ matrix.platform }}/libcef.so + tar -czf linux_${{ matrix.platform }}.tar.gz linux_${{ matrix.platform }} sha256sum linux_${{ matrix.platform }}.tar.gz > linux_${{ matrix.platform }}.tar.gz.sha256 - name: Copy s3cfg run: echo "${{ secrets.S3_CFG }}" > ~/.s3cfg @@ -59,7 +59,8 @@ jobs: cd native ren Release windows_${{ matrix.platform }} cd .. - tar -czf windows_${{ matrix.platform }}.tar.gz -C native . + move native/windows_${{ matrix.platform }} windows_${{ matrix.platform }} + tar -czf windows_${{ matrix.platform }}.tar.gz windows_${{ matrix.platform }} Get-FileHash -Algorithm SHA256 -Path "windows_${{ matrix.platform }}.tar.gz" | Out-File "windows_${{ matrix.platform }}.tar.gz.sha256" - name: Copy s3cfg run: echo "${{ secrets.S3_CFG }}" > "$HOME\AppData\Roaming\s3cmd.ini" @@ -84,8 +85,8 @@ jobs: mkdir jcef_build && cd jcef_build cmake -G "Ninja" -DPROJECT_ARCH=${{ matrix.platform }} -DCMAKE_BUILD_TYPE=Release .. ninja -j4 - mv native/Release native/macos_${{ matrix.platform }} - tar -czf macos_${{ matrix.platform }}.tar.gz -C native . + mv native/Release macos_${{ matrix.platform }} + tar -czf macos_${{ matrix.platform }}.tar.gz macos_${{ matrix.platform }} sha256sum macos_${{ matrix.platform }}.tar.gz > macos_${{ matrix.platform }}.tar.gz.sha256 - name: Copy s3cfg run: echo "${{ secrets.S3_CFG }}" > ~/.s3cfg From 45c6017e294b8db89eb7608cb029e85804b0b9d4 Mon Sep 17 00:00:00 2001 From: GiantLuigi4 <49770992+GiantLuigi4@users.noreply.github.com> Date: Sat, 12 Aug 2023 19:35:26 -0400 Subject: [PATCH 51/75] remove some unused code --- native/util.h | 26 +------------------------- native/util_linux.cpp | 42 ------------------------------------------ native/util_mac.mm | 34 ---------------------------------- native/util_win.cpp | 14 -------------- 4 files changed, 1 insertion(+), 115 deletions(-) diff --git a/native/util.h b/native/util.h index eba07452..58f1cfca 100644 --- a/native/util.h +++ b/native/util.h @@ -93,31 +93,7 @@ void AddCefBrowser(CefRefPtr browser); // Called by CefBrowser.close(true) to destroy the native browser window. void DestroyCefBrowser(CefRefPtr browser); -#if defined(OS_MACOSX) - -// Set the parent of |browserHandle|. If the parent is nullptr the browser will -// be parented to the TempWindow. -void SetParent(CefWindowHandle browserHandle, - jlong parentHandle, - base::OnceClosure callback); - -#else // !defined(OS_MACOSX) - -// Return the window handle for the specified canvas. -CefWindowHandle GetWindowHandle(JNIEnv* env, jobject canvas); - -// Set the parent of |browserHandle|. If the parent is nullptr the browser will -// be parented to the TempWindow. -void SetParent(CefWindowHandle browserHandle, - CefWindowHandle parentHandle, - base::OnceClosure callback); - -#if defined(OS_LINUX) -void SetParentSync(CefWindowHandle browserHandle, - CefWindowHandle parentHandle, - CriticalWait* waitCond, - base::OnceClosure callback); -#endif +#if !defined(OS_MACOSX) // Set the window bounds for |browserHandle|. void SetWindowBounds(CefWindowHandle browserHandle, const CefRect& contentRect); diff --git a/native/util_linux.cpp b/native/util_linux.cpp index 52807be0..d63ae676 100644 --- a/native/util_linux.cpp +++ b/native/util_linux.cpp @@ -26,18 +26,6 @@ void X_XMoveResizeWindow(unsigned long browserHandle, XFlush(xdisplay); } -void X_XReparentWindow(unsigned long browserHandle, - unsigned long parentDrawable) { - ::Display* xdisplay = (::Display*)TempWindow::GetDisplay(); - XReparentWindow(xdisplay, browserHandle, parentDrawable, 0, 0); - XFlush(xdisplay); -} - -void X_XSync(bool discard) { - ::Display* xdisplay = (::Display*)TempWindow::GetDisplay(); - XSync(xdisplay, discard); -} - } // namespace // This function is called by LifeSpanHandler::OnAfterCreated(). @@ -53,36 +41,6 @@ void DestroyCefBrowser(CefRefPtr browser) { browser->GetHost()->CloseBrowser(true); } -CefWindowHandle GetWindowHandle(JNIEnv* env, jobject canvas) { - return 0; -} - -void SetParent(CefWindowHandle browserHandle, - CefWindowHandle parentHandle, - base::OnceClosure callback) { - SetParentSync(browserHandle, parentHandle, nullptr, std::move(callback)); -} - -void SetParentSync(CefWindowHandle browserHandle, - CefWindowHandle parentHandle, - CriticalWait* waitCond, - base::OnceClosure callback) { - if (waitCond) { - waitCond->lock()->Lock(); - } - if (parentHandle == kNullWindowHandle) - parentHandle = TempWindow::GetWindowHandle(); - if (parentHandle != kNullWindowHandle && browserHandle != kNullWindowHandle) - X_XReparentWindow(browserHandle, parentHandle); - - if (waitCond) { - X_XSync(false); - waitCond->WakeUp(); - waitCond->lock()->Unlock(); - } - std::move(callback).Run(); -} - void SetWindowBounds(CefWindowHandle browserHandle, const CefRect& contentRect) { X_XMoveResizeWindow(browserHandle, contentRect.x, contentRect.y, diff --git a/native/util_mac.mm b/native/util_mac.mm index f7da32aa..527ad867 100644 --- a/native/util_mac.mm +++ b/native/util_mac.mm @@ -538,38 +538,4 @@ void DestroyCefBrowser(CefRefPtr browser) { } } -void SetParent(CefWindowHandle handle, - jlong parentHandle, - base::OnceClosure callback) { - base::RepeatingClosure* pCallback = new base::RepeatingClosure( - base::BindRepeating([](base::OnceClosure& cb) { std::move(cb).Run(); }, - OwnedRef(std::move(callback)))); - dispatch_async(dispatch_get_main_queue(), ^{ - g_browsers_lock_.Lock(); - bool browser_exists = g_browsers_.count(handle) > 0; - g_browsers_lock_.Unlock(); - if (!browser_exists) - return; - - CefBrowserContentView* browser_view = - (CefBrowserContentView*)[CAST_CEF_WINDOW_HANDLE_TO_NSVIEW(handle) - superview]; - [browser_view retain]; - [browser_view removeFromSuperview]; - - NSView* contentView; - if (parentHandle) { - NSWindow* window = (NSWindow*)parentHandle; - contentView = [window contentView]; - } else { - contentView = - CAST_CEF_WINDOW_HANDLE_TO_NSVIEW(TempWindow::GetWindowHandle()); - } - [contentView addSubview:browser_view]; - [browser_view release]; - pCallback->Run(); - delete pCallback; - }); -} - } // namespace util diff --git a/native/util_win.cpp b/native/util_win.cpp index 2bfc53e3..1754c6b4 100644 --- a/native/util_win.cpp +++ b/native/util_win.cpp @@ -306,20 +306,6 @@ void DestroyCefBrowser(CefRefPtr browser) { } } -CefWindowHandle GetWindowHandle(JNIEnv* env, jobject canvas) { - return 0; -} - -void SetParent(CefWindowHandle browserHandle, - CefWindowHandle parentHandle, - base::OnceClosure callback) { - if (parentHandle == kNullWindowHandle) - parentHandle = TempWindow::GetWindowHandle(); - if (parentHandle != kNullWindowHandle && browserHandle != kNullWindowHandle) - ::SetParent(browserHandle, parentHandle); - std::move(callback).Run(); -} - void SetWindowBounds(CefWindowHandle browserHandle, const CefRect& contentRect) { HRGN contentRgn = CreateRectRgn(contentRect.x, contentRect.y, From 99997925057ad0019c317e46a443ef2a1ae76136 Mon Sep 17 00:00:00 2001 From: GiantLuigi4 <49770992+GiantLuigi4@users.noreply.github.com> Date: Sat, 12 Aug 2023 22:12:52 -0400 Subject: [PATCH 52/75] remove some code from jni_util.h --- native/jni_util.h | 6 ------ 1 file changed, 6 deletions(-) diff --git a/native/jni_util.h b/native/jni_util.h index 1f94d34a..ee99d6d2 100644 --- a/native/jni_util.h +++ b/native/jni_util.h @@ -25,12 +25,6 @@ JavaVM* GetJVM(); void SetJavaClassLoader(JNIEnv* env, jobject javaClassLoader); jobject GetJavaClassLoader(); -#if defined(OS_WIN) -HWND GetHwndOfCanvas(jobject canvas, JNIEnv* env); -#elif defined(OS_LINUX) -unsigned long GetDrawableOfCanvas(jobject canvas, JNIEnv* env); -#endif - // Create a new JNI object and call the default constructor. jobject NewJNIObject(JNIEnv* env, jclass cls); jobject NewJNIObject(JNIEnv* env, const char* class_name); From abec58115a2426f7bc3ec830006d489b1f964dcd Mon Sep 17 00:00:00 2001 From: ds58 <30220598+ds58@users.noreply.github.com> Date: Sat, 12 Aug 2023 21:30:57 -0500 Subject: [PATCH 53/75] Update workflow events --- .github/workflows/build-jcef.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-jcef.yml b/.github/workflows/build-jcef.yml index 20cead50..fa97b385 100644 --- a/.github/workflows/build-jcef.yml +++ b/.github/workflows/build-jcef.yml @@ -4,7 +4,7 @@ on: push: branches: - master - pull_request: + pull_request_target: workflow_dispatch: jobs: From 59e83ef3da6b210beffb53d305a021b7d114aa47 Mon Sep 17 00:00:00 2001 From: ds58 <30220598+ds58@users.noreply.github.com> Date: Sat, 12 Aug 2023 21:42:11 -0500 Subject: [PATCH 54/75] Revert "Update workflow events" This reverts commit abec58115a2426f7bc3ec830006d489b1f964dcd. --- .github/workflows/build-jcef.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-jcef.yml b/.github/workflows/build-jcef.yml index fa97b385..20cead50 100644 --- a/.github/workflows/build-jcef.yml +++ b/.github/workflows/build-jcef.yml @@ -4,7 +4,7 @@ on: push: branches: - master - pull_request_target: + pull_request: workflow_dispatch: jobs: From 50a464040c4645eb08d3c426bbd8ce355498213e Mon Sep 17 00:00:00 2001 From: ds58 <30220598+ds58@users.noreply.github.com> Date: Sat, 12 Aug 2023 21:59:16 -0500 Subject: [PATCH 55/75] Update workflow events --- .github/workflows/build-jcef.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build-jcef.yml b/.github/workflows/build-jcef.yml index 20cead50..febfdf8d 100644 --- a/.github/workflows/build-jcef.yml +++ b/.github/workflows/build-jcef.yml @@ -4,7 +4,9 @@ on: push: branches: - master - pull_request: + pull_request_target: + types: + - labeled workflow_dispatch: jobs: From ec593c99d901112038b094a5aef6226671746320 Mon Sep 17 00:00:00 2001 From: GiantLuigi4 <49770992+GiantLuigi4@users.noreply.github.com> Date: Sat, 12 Aug 2023 23:01:42 -0400 Subject: [PATCH 56/75] remove some awt code from the java side --- java/org/cef/browser/CefBrowser.java | 6 ------ java/org/cef/browser/CefBrowserOsr.java | 12 ------------ java/org/cef/browser/CefBrowser_N.java | 12 ------------ 3 files changed, 30 deletions(-) diff --git a/java/org/cef/browser/CefBrowser.java b/java/org/cef/browser/CefBrowser.java index 43ae8f60..e73bae58 100644 --- a/java/org/cef/browser/CefBrowser.java +++ b/java/org/cef/browser/CefBrowser.java @@ -31,12 +31,6 @@ public interface CefBrowser { */ public void createImmediately(); - /** - * Get the underlying UI component (e.g. java.awt.Canvas). - * @return The underlying UI component. - */ - public Component getUIComponent(); - /** * Get the client associated with this browser. * @return The browser client. diff --git a/java/org/cef/browser/CefBrowserOsr.java b/java/org/cef/browser/CefBrowserOsr.java index 99c276e4..a09d92f0 100644 --- a/java/org/cef/browser/CefBrowserOsr.java +++ b/java/org/cef/browser/CefBrowserOsr.java @@ -31,13 +31,6 @@ public class CefBrowserOsr extends CefBrowser_N implements CefRenderHandler { private int depth_per_component = 8; private boolean isTransparent_; - protected final Component dummyComponent = new Component() { - @Override - public Point getLocationOnScreen() { - return new Point(0, 0); - } - }; - public CefBrowserOsr(CefClient client, String url, boolean transparent, CefRequestContext context) { this(client, url, transparent, context, null, null); } @@ -55,11 +48,6 @@ public void createImmediately() { createBrowserIfRequired(false); } - @Override - public Component getUIComponent() { - return dummyComponent; - } - @Override public CefRenderHandler getRenderHandler() { return this; diff --git a/java/org/cef/browser/CefBrowser_N.java b/java/org/cef/browser/CefBrowser_N.java index d641098b..6c3749f9 100644 --- a/java/org/cef/browser/CefBrowser_N.java +++ b/java/org/cef/browser/CefBrowser_N.java @@ -104,18 +104,6 @@ public synchronized boolean doClose() { return false; } - SwingUtilities.invokeLater(new Runnable() { - @Override - public void run() { - // Trigger close of the parent window. - Component parent = SwingUtilities.getRoot(getUIComponent()); - if (parent != null) { - parent.dispatchEvent( - new WindowEvent((Window) parent, WindowEvent.WINDOW_CLOSING)); - } - } - }); - // Cancel the close. return true; } From dd27745cf8686325119a6d515dfaa0b693e4e9bd Mon Sep 17 00:00:00 2001 From: ds58 <30220598+ds58@users.noreply.github.com> Date: Sat, 12 Aug 2023 22:46:23 -0500 Subject: [PATCH 57/75] Checkout to github.ref in workflow --- .github/workflows/build-jcef.yml | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build-jcef.yml b/.github/workflows/build-jcef.yml index febfdf8d..8109546b 100644 --- a/.github/workflows/build-jcef.yml +++ b/.github/workflows/build-jcef.yml @@ -18,7 +18,10 @@ jobs: steps: - name: Upload mask run: echo "::add-mask::${{ secrets.UPLOAD_URL }}" - - uses: actions/checkout@v3 + - name: Checkout code + uses: actions/checkout@v3 + with: + ref: ${{ github.ref }} - name: Install deps and build run: | sudo apt update @@ -46,7 +49,10 @@ jobs: steps: - name: Upload mask run: echo "::add-mask::${{ secrets.UPLOAD_URL }}" - - uses: actions/checkout@v3 + - name: Checkout code + uses: actions/checkout@v3 + with: + ref: ${{ github.ref }} - uses: ilammy/msvc-dev-cmd@v1 - name: Install s3cmd run: | @@ -78,7 +84,10 @@ jobs: steps: - name: Upload mask run: echo "::add-mask::${{ secrets.UPLOAD_URL }}" - - uses: actions/checkout@v3 + - name: Checkout code + uses: actions/checkout@v3 + with: + ref: ${{ github.ref }} - run: | brew install ninja brew install coreutils From 65460f6d6872b606bbb31652eb9e24882e3070cf Mon Sep 17 00:00:00 2001 From: ds58 <30220598+ds58@users.noreply.github.com> Date: Sat, 12 Aug 2023 22:54:38 -0500 Subject: [PATCH 58/75] Checkout to pr ref in workflow --- .github/workflows/build-jcef.yml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/.github/workflows/build-jcef.yml b/.github/workflows/build-jcef.yml index 8109546b..1f3c2ba6 100644 --- a/.github/workflows/build-jcef.yml +++ b/.github/workflows/build-jcef.yml @@ -21,7 +21,7 @@ jobs: - name: Checkout code uses: actions/checkout@v3 with: - ref: ${{ github.ref }} + ref: ${{ github.event.pull_request.head.ref }} - name: Install deps and build run: | sudo apt update @@ -39,8 +39,8 @@ jobs: run: echo "${{ secrets.S3_CFG }}" > ~/.s3cfg - name: Upload java-cef build run: | - s3cmd put -P /home/runner/work/java-cef/java-cef/jcef_build/linux_${{ matrix.platform }}.tar.gz s3://mcef-us-1/java-cef-builds/${{ github.sha }}/linux_${{ matrix.platform }}.tar.gz - s3cmd put -P /home/runner/work/java-cef/java-cef/jcef_build/linux_${{ matrix.platform }}.tar.gz.sha256 s3://mcef-us-1/java-cef-builds/${{ github.sha }}/linux_${{ matrix.platform }}.tar.gz.sha256 + s3cmd put -P /home/runner/work/java-cef/java-cef/jcef_build/linux_${{ matrix.platform }}.tar.gz s3://mcef-us-1/java-cef-builds/${{ github.event.pull_request.head.sha }}/linux_${{ matrix.platform }}.tar.gz + s3cmd put -P /home/runner/work/java-cef/java-cef/jcef_build/linux_${{ matrix.platform }}.tar.gz.sha256 s3://mcef-us-1/java-cef-builds/${{ github.event.pull_request.head.sha }}/linux_${{ matrix.platform }}.tar.gz.sha256 java-cef-windows: runs-on: [windows-2022] strategy: @@ -52,7 +52,7 @@ jobs: - name: Checkout code uses: actions/checkout@v3 with: - ref: ${{ github.ref }} + ref: ${{ github.event.pull_request.head.ref }} - uses: ilammy/msvc-dev-cmd@v1 - name: Install s3cmd run: | @@ -74,8 +74,8 @@ jobs: run: echo "${{ secrets.S3_CFG }}" > "$HOME\AppData\Roaming\s3cmd.ini" - name: Upload java-cef build run: | - python D:\s3cmd\s3cmd-master\s3cmd put -P D:\a\java-cef\java-cef\jcef_build\windows_${{ matrix.platform }}.tar.gz s3://mcef-us-1/java-cef-builds/${{ github.sha }}/windows_${{ matrix.platform }}.tar.gz - python D:\s3cmd\s3cmd-master\s3cmd put -P D:\a\java-cef\java-cef\jcef_build\windows_${{ matrix.platform }}.tar.gz.sha256 s3://mcef-us-1/java-cef-builds/${{ github.sha }}/windows_${{ matrix.platform }}.tar.gz.sha256 + python D:\s3cmd\s3cmd-master\s3cmd put -P D:\a\java-cef\java-cef\jcef_build\windows_${{ matrix.platform }}.tar.gz s3://mcef-us-1/java-cef-builds/${{ github.event.pull_request.head.sha }}/windows_${{ matrix.platform }}.tar.gz + python D:\s3cmd\s3cmd-master\s3cmd put -P D:\a\java-cef\java-cef\jcef_build\windows_${{ matrix.platform }}.tar.gz.sha256 s3://mcef-us-1/java-cef-builds/${{ github.event.pull_request.head.sha }}/windows_${{ matrix.platform }}.tar.gz.sha256 java-cef-macos: runs-on: [macos-12] strategy: @@ -87,7 +87,7 @@ jobs: - name: Checkout code uses: actions/checkout@v3 with: - ref: ${{ github.ref }} + ref: ${{ github.event.pull_request.head.ref }} - run: | brew install ninja brew install coreutils @@ -103,5 +103,5 @@ jobs: run: echo "${{ secrets.S3_CFG }}" > ~/.s3cfg - name: Upload java-cef build run: | - s3cmd put -P /Users/runner/work/java-cef/java-cef/jcef_build/macos_${{ matrix.platform }}.tar.gz s3://mcef-us-1/java-cef-builds/${{ github.sha }}/macos_${{ matrix.platform }}.tar.gz - s3cmd put -P /Users/runner/work/java-cef/java-cef/jcef_build/macos_${{ matrix.platform }}.tar.gz.sha256 s3://mcef-us-1/java-cef-builds/${{ github.sha }}/macos_${{ matrix.platform }}.tar.gz.sha256 + s3cmd put -P /Users/runner/work/java-cef/java-cef/jcef_build/macos_${{ matrix.platform }}.tar.gz s3://mcef-us-1/java-cef-builds/${{ github.event.pull_request.head.sha }}/macos_${{ matrix.platform }}.tar.gz + s3cmd put -P /Users/runner/work/java-cef/java-cef/jcef_build/macos_${{ matrix.platform }}.tar.gz.sha256 s3://mcef-us-1/java-cef-builds/${{ github.event.pull_request.head.sha }}/macos_${{ matrix.platform }}.tar.gz.sha256 From c8523c80f65bf300af311c5268e0a5fe5fcbd7d2 Mon Sep 17 00:00:00 2001 From: ds58 <30220598+ds58@users.noreply.github.com> Date: Sat, 12 Aug 2023 23:02:07 -0500 Subject: [PATCH 59/75] Revert workflow changes --- .github/workflows/build-jcef.yml | 30 +++++++++--------------------- 1 file changed, 9 insertions(+), 21 deletions(-) diff --git a/.github/workflows/build-jcef.yml b/.github/workflows/build-jcef.yml index 1f3c2ba6..95349ce3 100644 --- a/.github/workflows/build-jcef.yml +++ b/.github/workflows/build-jcef.yml @@ -4,9 +4,6 @@ on: push: branches: - master - pull_request_target: - types: - - labeled workflow_dispatch: jobs: @@ -18,10 +15,7 @@ jobs: steps: - name: Upload mask run: echo "::add-mask::${{ secrets.UPLOAD_URL }}" - - name: Checkout code - uses: actions/checkout@v3 - with: - ref: ${{ github.event.pull_request.head.ref }} + - uses: actions/checkout@v3 - name: Install deps and build run: | sudo apt update @@ -39,8 +33,8 @@ jobs: run: echo "${{ secrets.S3_CFG }}" > ~/.s3cfg - name: Upload java-cef build run: | - s3cmd put -P /home/runner/work/java-cef/java-cef/jcef_build/linux_${{ matrix.platform }}.tar.gz s3://mcef-us-1/java-cef-builds/${{ github.event.pull_request.head.sha }}/linux_${{ matrix.platform }}.tar.gz - s3cmd put -P /home/runner/work/java-cef/java-cef/jcef_build/linux_${{ matrix.platform }}.tar.gz.sha256 s3://mcef-us-1/java-cef-builds/${{ github.event.pull_request.head.sha }}/linux_${{ matrix.platform }}.tar.gz.sha256 + s3cmd put -P /home/runner/work/java-cef/java-cef/jcef_build/linux_${{ matrix.platform }}.tar.gz s3://mcef-us-1/java-cef-builds/${{ github.sha }}/linux_${{ matrix.platform }}.tar.gz + s3cmd put -P /home/runner/work/java-cef/java-cef/jcef_build/linux_${{ matrix.platform }}.tar.gz.sha256 s3://mcef-us-1/java-cef-builds/${{ github.sha }}/linux_${{ matrix.platform }}.tar.gz.sha256 java-cef-windows: runs-on: [windows-2022] strategy: @@ -49,10 +43,7 @@ jobs: steps: - name: Upload mask run: echo "::add-mask::${{ secrets.UPLOAD_URL }}" - - name: Checkout code - uses: actions/checkout@v3 - with: - ref: ${{ github.event.pull_request.head.ref }} + - uses: actions/checkout@v3 - uses: ilammy/msvc-dev-cmd@v1 - name: Install s3cmd run: | @@ -74,8 +65,8 @@ jobs: run: echo "${{ secrets.S3_CFG }}" > "$HOME\AppData\Roaming\s3cmd.ini" - name: Upload java-cef build run: | - python D:\s3cmd\s3cmd-master\s3cmd put -P D:\a\java-cef\java-cef\jcef_build\windows_${{ matrix.platform }}.tar.gz s3://mcef-us-1/java-cef-builds/${{ github.event.pull_request.head.sha }}/windows_${{ matrix.platform }}.tar.gz - python D:\s3cmd\s3cmd-master\s3cmd put -P D:\a\java-cef\java-cef\jcef_build\windows_${{ matrix.platform }}.tar.gz.sha256 s3://mcef-us-1/java-cef-builds/${{ github.event.pull_request.head.sha }}/windows_${{ matrix.platform }}.tar.gz.sha256 + python D:\s3cmd\s3cmd-master\s3cmd put -P D:\a\java-cef\java-cef\jcef_build\windows_${{ matrix.platform }}.tar.gz s3://mcef-us-1/java-cef-builds/${{ github.sha }}/windows_${{ matrix.platform }}.tar.gz + python D:\s3cmd\s3cmd-master\s3cmd put -P D:\a\java-cef\java-cef\jcef_build\windows_${{ matrix.platform }}.tar.gz.sha256 s3://mcef-us-1/java-cef-builds/${{ github.sha }}/windows_${{ matrix.platform }}.tar.gz.sha256 java-cef-macos: runs-on: [macos-12] strategy: @@ -84,10 +75,7 @@ jobs: steps: - name: Upload mask run: echo "::add-mask::${{ secrets.UPLOAD_URL }}" - - name: Checkout code - uses: actions/checkout@v3 - with: - ref: ${{ github.event.pull_request.head.ref }} + - uses: actions/checkout@v3 - run: | brew install ninja brew install coreutils @@ -103,5 +91,5 @@ jobs: run: echo "${{ secrets.S3_CFG }}" > ~/.s3cfg - name: Upload java-cef build run: | - s3cmd put -P /Users/runner/work/java-cef/java-cef/jcef_build/macos_${{ matrix.platform }}.tar.gz s3://mcef-us-1/java-cef-builds/${{ github.event.pull_request.head.sha }}/macos_${{ matrix.platform }}.tar.gz - s3cmd put -P /Users/runner/work/java-cef/java-cef/jcef_build/macos_${{ matrix.platform }}.tar.gz.sha256 s3://mcef-us-1/java-cef-builds/${{ github.event.pull_request.head.sha }}/macos_${{ matrix.platform }}.tar.gz.sha256 + s3cmd put -P /Users/runner/work/java-cef/java-cef/jcef_build/macos_${{ matrix.platform }}.tar.gz s3://mcef-us-1/java-cef-builds/${{ github.sha }}/macos_${{ matrix.platform }}.tar.gz + s3cmd put -P /Users/runner/work/java-cef/java-cef/jcef_build/macos_${{ matrix.platform }}.tar.gz.sha256 s3://mcef-us-1/java-cef-builds/${{ github.sha }}/macos_${{ matrix.platform }}.tar.gz.sha256 From 162b91d6399c7340e868f2e7d436d41a3de93679 Mon Sep 17 00:00:00 2001 From: ds58 <30220598+ds58@users.noreply.github.com> Date: Sat, 12 Aug 2023 23:15:47 -0500 Subject: [PATCH 60/75] Make tests compile --- java/tests/detailed/BrowserFrame.java | 2 -- java/tests/detailed/MainFrame.java | 1 - java/tests/detailed/dialog/DevToolsDialog.java | 1 - java/tests/detailed/ui/MenuBar.java | 2 -- java/tests/junittests/TestFrame.java | 1 - java/tests/simple/MainFrame.java | 3 --- 6 files changed, 10 deletions(-) diff --git a/java/tests/detailed/BrowserFrame.java b/java/tests/detailed/BrowserFrame.java index dedcd1f8..25beacf3 100644 --- a/java/tests/detailed/BrowserFrame.java +++ b/java/tests/detailed/BrowserFrame.java @@ -125,10 +125,8 @@ public void onBeforeClose(CefBrowser browser) { public void removeBrowser(Runnable r) { System.out.println("BrowserFrame.removeBrowser"); afterParentChangedAction_ = r; - remove(browser_.getUIComponent()); // The removeNotify() notification should be sent as a result of calling remove(). // However, it isn't in all cases so we do it manually here. - browser_.getUIComponent().removeNotify(); browser_ = null; } diff --git a/java/tests/detailed/MainFrame.java b/java/tests/detailed/MainFrame.java index ea2d720c..5b1efeb5 100644 --- a/java/tests/detailed/MainFrame.java +++ b/java/tests/detailed/MainFrame.java @@ -239,7 +239,6 @@ public void onTakeFocus(CefBrowser browser, boolean next) { if (createImmediately) browser.createImmediately(); // Add the browser to the UI. - contentPanel.add(getBrowser().getUIComponent(), BorderLayout.CENTER); MenuBar menuBar = new MenuBar( this, browser, control_pane_, downloadDialog, CefCookieManager.getGlobalManager()); diff --git a/java/tests/detailed/dialog/DevToolsDialog.java b/java/tests/detailed/dialog/DevToolsDialog.java index d1fb3d8d..74a3a766 100644 --- a/java/tests/detailed/dialog/DevToolsDialog.java +++ b/java/tests/detailed/dialog/DevToolsDialog.java @@ -29,7 +29,6 @@ public DevToolsDialog(Frame owner, String title, CefBrowser browser, Point inspe setLocation(owner.getLocation().x + 20, owner.getLocation().y + 20); devTools_ = browser.getDevTools(inspectAt); - add(devTools_.getUIComponent()); addComponentListener(new ComponentAdapter() { @Override diff --git a/java/tests/detailed/ui/MenuBar.java b/java/tests/detailed/ui/MenuBar.java index c69ae215..a6fe40bc 100644 --- a/java/tests/detailed/ui/MenuBar.java +++ b/java/tests/detailed/ui/MenuBar.java @@ -408,7 +408,6 @@ public void actionPerformed(ActionEvent e) { if (reparentButton.getText().equals("Reparent <")) { owner_.removeBrowser(new Runnable() { public void run() { - newFrame.add(browser_.getUIComponent(), BorderLayout.CENTER); newFrame.setBrowser(browser_); reparentButton.setText("Reparent >"); reparentPending_ = false; @@ -420,7 +419,6 @@ public void run() { JRootPane rootPane = (JRootPane) owner_.getComponent(0); Container container = rootPane.getContentPane(); JPanel panel = (JPanel) container.getComponent(0); - panel.add(browser_.getUIComponent()); owner_.setBrowser(browser_); owner_.revalidate(); reparentButton.setText("Reparent <"); diff --git a/java/tests/junittests/TestFrame.java b/java/tests/junittests/TestFrame.java index 78151ba4..1650849f 100644 --- a/java/tests/junittests/TestFrame.java +++ b/java/tests/junittests/TestFrame.java @@ -108,7 +108,6 @@ protected void createBrowser(String startURL) { browser_ = client_.createBrowser(startURL, false /* isTransparent */); assertNotNull(browser_); - getContentPane().add(browser_.getUIComponent(), BorderLayout.CENTER); pack(); setSize(800, 600); setVisible(true); diff --git a/java/tests/simple/MainFrame.java b/java/tests/simple/MainFrame.java index 9d68fd1c..822c4c8f 100644 --- a/java/tests/simple/MainFrame.java +++ b/java/tests/simple/MainFrame.java @@ -46,7 +46,6 @@ public class MainFrame extends JFrame { private final CefApp cefApp_; private final CefClient client_; private final CefBrowser browser_; - private final Component browerUI_; private boolean browserFocus_ = true; /** @@ -105,7 +104,6 @@ public void stateHasChanged(org.cef.CefApp.CefAppState state) { // The UI component is inherited from a java.awt.Component and therefore // it can be embedded into any AWT UI. browser_ = client_.createBrowser(startURL, isTransparent); - browerUI_ = browser_.getUIComponent(); // (4) For this minimal browser, we need only a text field to enter an URL // we want to navigate to and a CefBrowser window to display the content @@ -160,7 +158,6 @@ public void onTakeFocus(CefBrowser browser, boolean next) { // (5) All UI components are assigned to the default content pane of this // JFrame and afterwards the frame is made visible to the user. getContentPane().add(address_, BorderLayout.NORTH); - getContentPane().add(browerUI_, BorderLayout.CENTER); pack(); setSize(800, 600); setVisible(true); From a6e43256e06d8307f636d5a6edc71c11bfeb66d3 Mon Sep 17 00:00:00 2001 From: ds58 <30220598+ds58@users.noreply.github.com> Date: Sun, 13 Aug 2023 02:04:25 -0500 Subject: [PATCH 61/75] Scrolling improvements, especially on macos --- java/org/cef/event/CefMouseWheelEvent.java | 8 ++++---- native/CefBrowser_N.cpp | 7 ++++--- native/jni_util.cpp | 14 ++++++++++++++ native/jni_util.h | 7 +++++++ 4 files changed, 29 insertions(+), 7 deletions(-) diff --git a/java/org/cef/event/CefMouseWheelEvent.java b/java/org/cef/event/CefMouseWheelEvent.java index 54a46f23..bf9769c4 100644 --- a/java/org/cef/event/CefMouseWheelEvent.java +++ b/java/org/cef/event/CefMouseWheelEvent.java @@ -9,13 +9,13 @@ public class CefMouseWheelEvent { // may remove the getters, or maybe add setters, or maybe move to private // not sure yet public int id; - public int delta; + public double delta; public int x; public int y; public int modifiers; public int amount = 32; // TODO: might want to make this change dependent on system? - public CefMouseWheelEvent(int id, int x, int y, int delta, int modifiers) { + public CefMouseWheelEvent(int id, int x, int y, double delta, int modifiers) { this.id = id; this.x = x; this.y = y; @@ -27,7 +27,7 @@ public int getScrollType() { return id; } - public int getWheelRotation() { + public double getWheelRotation() { return delta; } @@ -43,7 +43,7 @@ public int getModifiers() { return modifiers; } - public int getUnitsToScroll() { + public double getUnitsToScroll() { return amount * delta; } } diff --git a/native/CefBrowser_N.cpp b/native/CefBrowser_N.cpp index bef1da00..890fd0c0 100644 --- a/native/CefBrowser_N.cpp +++ b/native/CefBrowser_N.cpp @@ -1843,10 +1843,11 @@ Java_org_cef_browser_CefBrowser_1N_N_1SendMouseWheelEvent( JNI_STATIC_DEFINE_INT(env, objClass, WHEEL_UNIT_SCROLL); - int scroll_type, delta, x, y, modifiers; + int scroll_type, x, y, modifiers; + double delta; if (!CallJNIMethodI_V(env, objClass, mouse_wheel_event, "getScrollType", &scroll_type) || - !CallJNIMethodI_V(env, objClass, mouse_wheel_event, "getWheelRotation", + !CallJNIMethodD_V(env, objClass, mouse_wheel_event, "getWheelRotation", &delta) || !CallJNIMethodI_V(env, objClass, mouse_wheel_event, "getX", &x) || !CallJNIMethodI_V(env, objClass, mouse_wheel_event, "getY", &y) || @@ -1863,7 +1864,7 @@ Java_org_cef_browser_CefBrowser_1N_N_1SendMouseWheelEvent( if (scroll_type == 0) { // WHEEL_UNIT_SCROLL // Use the smarter version that considers platform settings. - CallJNIMethodI_V(env, objClass, mouse_wheel_event, "getUnitsToScroll", &delta); + CallJNIMethodD_V(env, objClass, mouse_wheel_event, "getUnitsToScroll", &delta); } double deltaX = 0, deltaY = 0; diff --git a/native/jni_util.cpp b/native/jni_util.cpp index 27c104d9..14f126a2 100644 --- a/native/jni_util.cpp +++ b/native/jni_util.cpp @@ -959,6 +959,20 @@ bool CallJNIMethodC_V(JNIEnv* env, return false; } +bool CallJNIMethodD_V(JNIEnv* env, + jclass cls, + jobject obj, + const char* method_name, + double* value) { + jmethodID methodID = env->GetMethodID(cls, method_name, "()D"); + if (methodID) { + *value = env->CallDoubleMethod(obj, methodID); + return true; + } + env->ExceptionClear(); + return false; +} + CefSize GetJNISize(JNIEnv* env, jobject obj) { CefSize size; diff --git a/native/jni_util.h b/native/jni_util.h index ee99d6d2..82680e35 100644 --- a/native/jni_util.h +++ b/native/jni_util.h @@ -169,6 +169,13 @@ bool CallJNIMethodC_V(JNIEnv* env, const char* method_name, char16* value); +// Call a JNI method that returns a double and accepts no arguments. +bool CallJNIMethodD_V(JNIEnv* env, + jclass cls, + jobject obj, + const char* method_name, + double* value); + // Rertieve the CefSize equivalent of a java.awt.Dimension. CefSize GetJNISize(JNIEnv* env, jobject obj); From 8a4310236b23bc8088abb90e811a17eddeda66aa Mon Sep 17 00:00:00 2001 From: GiantLuigi4 <49770992+GiantLuigi4@users.noreply.github.com> Date: Fri, 22 Sep 2023 22:34:51 -0400 Subject: [PATCH 62/75] start of audio stuff --- java/org/cef/CefClient.java | 50 +++++++----- java/org/cef/handler/CefAudioHandler.java | 23 ++++++ .../cef/handler/CefAudioHandlerAdapter.java | 29 +++++++ java/org/cef/handler/CefClientHandler.java | 13 +++- native/CefClientHandler.cpp | 9 +++ native/CefClientHandler.h | 10 +++ native/audio_handler.cpp | 77 +++++++++++++++++++ native/audio_handler.h | 36 +++++++++ native/client_handler.cpp | 5 ++ 9 files changed, 231 insertions(+), 21 deletions(-) create mode 100644 java/org/cef/handler/CefAudioHandler.java create mode 100644 java/org/cef/handler/CefAudioHandlerAdapter.java create mode 100644 native/audio_handler.cpp create mode 100644 native/audio_handler.h diff --git a/java/org/cef/CefClient.java b/java/org/cef/CefClient.java index 50880cd4..3025e061 100644 --- a/java/org/cef/CefClient.java +++ b/java/org/cef/CefClient.java @@ -21,24 +21,7 @@ import org.cef.callback.CefMenuModel; import org.cef.callback.CefPrintDialogCallback; import org.cef.callback.CefPrintJobCallback; -import org.cef.handler.CefClientHandler; -import org.cef.handler.CefContextMenuHandler; -import org.cef.handler.CefDialogHandler; -import org.cef.handler.CefDisplayHandler; -import org.cef.handler.CefDownloadHandler; -import org.cef.handler.CefDragHandler; -import org.cef.handler.CefFocusHandler; -import org.cef.handler.CefJSDialogHandler; -import org.cef.handler.CefKeyboardHandler; -import org.cef.handler.CefLifeSpanHandler; -import org.cef.handler.CefLoadHandler; -import org.cef.handler.CefPrintHandler; -import org.cef.handler.CefRenderHandler; -import org.cef.handler.CefRequestHandler; -import org.cef.handler.CefResourceHandler; -import org.cef.handler.CefResourceRequestHandler; -import org.cef.handler.CefScreenInfo; -import org.cef.handler.CefWindowHandler; +import org.cef.handler.*; import org.cef.misc.BoolRef; import org.cef.misc.CefPrintSettings; import org.cef.misc.StringRef; @@ -66,7 +49,7 @@ public class CefClient extends CefClientHandler implements CefContextMenuHandler, CefDialogHandler, CefDisplayHandler, CefDownloadHandler, CefDragHandler, CefFocusHandler, CefJSDialogHandler, CefKeyboardHandler, CefLifeSpanHandler, CefLoadHandler, CefPrintHandler, CefRenderHandler, - CefRequestHandler, CefWindowHandler { + CefRequestHandler, CefWindowHandler, CefAudioHandler { private HashMap browser_ = new HashMap(); private CefContextMenuHandler contextMenuHandler_ = null; private CefDialogHandler dialogHandler_ = null; @@ -532,6 +515,7 @@ private void cleanupBrowser(int identifier) { removeContextMenuHandler(this); removeDialogHandler(this); removeDisplayHandler(this); + removeAudioHandler(this); removeDownloadHandler(this); removeDragHandler(this); removeFocusHandler(this); @@ -808,4 +792,32 @@ public void onMouseEvent( public boolean getScreenInfo(CefBrowser arg0, CefScreenInfo arg1) { return false; } + + // CefAudioHandler + + + @Override + public int getAudioParameters(CefBrowser browser, Object params) { + return 0; // TODO + } + + @Override + public void onAudioStreamStarted(CefBrowser browser, Object params, int channels) { + // TODO + } + + @Override + public void onAudioStreamPacket(CefBrowser browser, float[][] data, int frames, long pts) { + // TODO + } + + @Override + public void onAudioStreamStopped(CefBrowser browser) { + // TODO + } + + @Override + public void onAudioStreamError(CefBrowser browser, String text) { + // TODO + } } diff --git a/java/org/cef/handler/CefAudioHandler.java b/java/org/cef/handler/CefAudioHandler.java new file mode 100644 index 00000000..fc07fbb4 --- /dev/null +++ b/java/org/cef/handler/CefAudioHandler.java @@ -0,0 +1,23 @@ +// Copyright (c) 2014 The Chromium Embedded Framework Authors. All rights +// reserved. Use of this source code is governed by a BSD-style license that +// can be found in the LICENSE file. + +package org.cef.handler; + +import org.cef.browser.CefBrowser; + +/** + * Implement this interface to handle events related to audio playing. + * The methods of this class will be called on the UI thread. + */ +public interface CefAudioHandler { + int getAudioParameters(CefBrowser browser, Object params); + + void onAudioStreamStarted(CefBrowser browser, Object params, int channels); + + void onAudioStreamPacket(CefBrowser browser, float[][] data, int frames, long pts); + + void onAudioStreamStopped(CefBrowser browser); + + void onAudioStreamError(CefBrowser browser, String text); +} diff --git a/java/org/cef/handler/CefAudioHandlerAdapter.java b/java/org/cef/handler/CefAudioHandlerAdapter.java new file mode 100644 index 00000000..c9f96edb --- /dev/null +++ b/java/org/cef/handler/CefAudioHandlerAdapter.java @@ -0,0 +1,29 @@ +// Copyright (c) 2014 The Chromium Embedded Framework Authors. All rights +// reserved. Use of this source code is governed by a BSD-style license that +// can be found in the LICENSE file. + +package org.cef.handler; + +import org.cef.browser.CefBrowser; + +/** + * Implement this interface to handle events related to audio playing. + * The methods of this class will be called on the UI thread. + */ +public abstract class CefAudioHandlerAdapter implements CefAudioHandler { + public int getAudioParameters(CefBrowser browser, Object params) { + return 0; // TODO + } + + public void onAudioStreamStarted(CefBrowser browser, Object params, int channels) { + } + + public void onAudioStreamPacket(CefBrowser browser, float[][] data, int frames, long pts) { + } + + public void onAudioStreamStopped(CefBrowser browser) { + } + + public void onAudioStreamError(CefBrowser browser, String text) { + } +} diff --git a/java/org/cef/handler/CefClientHandler.java b/java/org/cef/handler/CefClientHandler.java index 6a263a8e..916af719 100644 --- a/java/org/cef/handler/CefClientHandler.java +++ b/java/org/cef/handler/CefClientHandler.java @@ -198,8 +198,16 @@ protected void removeDisplayHandler(CefDisplayHandler h) { err.printStackTrace(); } } + + protected void removeAudioHandler(CefAudioHandler h) { + try { + N_removeAudioHandler(h); + } catch (UnsatisfiedLinkError err) { + err.printStackTrace(); + } + } - protected void removeDownloadHandler(CefDisplayHandler h) { + protected void removeDownloadHandler(CefDownloadHandler h) { try { N_removeDownloadHandler(h); } catch (UnsatisfiedLinkError err) { @@ -301,7 +309,8 @@ protected void removeWindowHandler(CefWindowHandler h) { private final native void N_removeContextMenuHandler(CefContextMenuHandler h); private final native void N_removeDialogHandler(CefDialogHandler h); private final native void N_removeDisplayHandler(CefDisplayHandler h); - private final native void N_removeDownloadHandler(CefDisplayHandler h); + private final native void N_removeAudioHandler(CefAudioHandler h); + private final native void N_removeDownloadHandler(CefDownloadHandler h); private final native void N_removeDragHandler(CefDragHandler h); private final native void N_removeFocusHandler(CefFocusHandler h); private final native void N_removeJSDialogHandler(CefJSDialogHandler h); diff --git a/native/CefClientHandler.cpp b/native/CefClientHandler.cpp index 8abbaf6a..9ac33878 100644 --- a/native/CefClientHandler.cpp +++ b/native/CefClientHandler.cpp @@ -54,6 +54,15 @@ Java_org_cef_handler_CefClientHandler_N_1removeDisplayHandler( "CefDisplayHandler"); } +JNIEXPORT void JNICALL +Java_org_cef_handler_CefClientHandler_N_1removeAudioHandler( + JNIEnv* env, + jobject clientHandler, + jobject audioHandler) { + SetCefForJNIObject(env, audioHandler, nullptr, + "CefAudioHandler"); +} + JNIEXPORT void JNICALL Java_org_cef_handler_CefClientHandler_N_1removeDownloadHandler( JNIEnv* env, diff --git a/native/CefClientHandler.h b/native/CefClientHandler.h index 9867c452..7b552958 100644 --- a/native/CefClientHandler.h +++ b/native/CefClientHandler.h @@ -56,6 +56,16 @@ Java_org_cef_handler_CefClientHandler_N_1removeDisplayHandler(JNIEnv*, jobject, jobject); +/* + * Class: org_cef_handler_CefClientHandler + * Method: N_removeAudioHandler + * Signature: (Lorg/cef/handler/CefAudioHandler;)V + */ +JNIEXPORT void JNICALL +Java_org_cef_handler_CefClientHandler_N_1removeAudioHandler(JNIEnv*, + jobject, + jobject); + /* * Class: org_cef_handler_CefClientHandler * Method: N_removeDownloadHandler diff --git a/native/audio_handler.cpp b/native/audio_handler.cpp new file mode 100644 index 00000000..db6ee274 --- /dev/null +++ b/native/audio_handler.cpp @@ -0,0 +1,77 @@ +// Copyright (c) 2014 The Chromium Embedded Framework Authors. All rights +// reserved. Use of this source code is governed by a BSD-style license that +// can be found in the LICENSE file. + +#include "audio_handler.h" + +#include "jni_util.h" + +AudioHandler::AudioHandler(JNIEnv* env, jobject handler) + : handle_(env, handler) {} + +int AudioHandler::GetAudioParameters(CefRefPtr browser, + cef_audio_parameters_t* params) { + ScopedJNIEnv env; + if (!env) + return 0; + + ScopedJNIBrowser jbrowser(env, browser); + + return JNI_CALL_INT_METHOD(env, handle_, "getAudioParameters", + "(Lorg/cef/browser/CefBrowser;Ljava/lang/Object;)I", + jbrowser.get(), nullptr); +} + +void AudioHandler::OnAudioStreamStarted(CefRefPtr browser, + cef_audio_parameters_t params, int channels) { + ScopedJNIEnv env; + if (!env) + return; + + ScopedJNIBrowser jbrowser(env, browser); + + JNI_CALL_VOID_METHOD(env, handle_, "onAudioStreamStarted", + "(Lorg/cef/browser/CefBrowser;Ljava/lang/Object;I)V", + jbrowser.get(), nullptr, channels); +} + +void AudioHandler::OnAudioStreamPacket(CefRefPtr browser, float** data, int frames, long long pts) { + ScopedJNIEnv env; + if (!env) + return false; + + ScopedJNIBrowser jbrowser(env, browser); + ScopedJNIString jtext(env, text); + jboolean jreturn = JNI_FALSE; + + // TODO: this is based on a bit of an assumption + JNI_CALL_METHOD(env, handle_, "onAudioStreamPacket", + "(Lorg/cef/browser/CefBrowser;Ljava/lang/String;[[FIL]])Z", Boolean, + jreturn, jbrowser.get(), jtext.get()); // TODO: +} + +void AudioHandler::OnAudioStreamStopped(CefRefPtr browser) { + ScopedJNIEnv env; + if (!env) + return; + + ScopedJNIBrowser jbrowser(env, browser); + + JNI_CALL_VOID_METHOD(env, handle_, "onAudioStreamStopped", + "(Lorg/cef/browser/CefBrowser;)V", + jbrowser.get()); +} + +void AudioHandler::OnAudioStreamError(CefRefPtr browser, + const CefString& text) { + ScopedJNIEnv env; + if (!env) + return false; + + ScopedJNIBrowser jbrowser(env, browser); + ScopedJNIString jtext(env, text); + + JNI_CALL_VOID_METHOD(env, handle_, "onAudioStreamError", + "(Lorg/cef/browser/CefBrowser;Ljava/lang/String;)V", + jbrowser.get(), text.get()); +} diff --git a/native/audio_handler.h b/native/audio_handler.h new file mode 100644 index 00000000..dfe25097 --- /dev/null +++ b/native/audio_handler.h @@ -0,0 +1,36 @@ +// Copyright (c) 2014 The Chromium Embedded Framework Authors. All rights +// reserved. Use of this source code is governed by a BSD-style license that +// can be found in the LICENSE file. + +#ifndef JCEF_NATIVE_DISPLAY_HANDLER_H_ +#define JCEF_NATIVE_DISPLAY_HANDLER_H_ +#pragma once + +#include + +#include "include/cef_audio_handler_capi.h" + +#include "jni_scoped_helpers.h" + +// DisplayHandler implementation. +class AudioHandler : public CefAudioHandler { + public: + AudioHandler(JNIEnv* env, jobject handler); + + // CefDisplayHandler methods: + int GetAudioParameters(CefRefPtr browser, + cef_audio_parameters_t params) override; + void OnAudioStreamStarted(CefRefPtr browser, + cef_audio_parameters_t params, int channels) override; + bool OnAudioStreamPacket(CefRefPtr browser, float** data, int frames, long long pts) override; + void OnAudioStreamStopped(CefRefPtr browser) override; + void OnAudioStreamError(CefRefPtr browser, CefString& text) override; + + protected: + ScopedJNIObjectGlobal handle_; + + // Include the default reference counting implementation. + IMPLEMENT_REFCOUNTING(AudioHandler); +}; + +#endif // JCEF_NATIVE_DISPLAY_HANDLER_H_ diff --git a/native/client_handler.cpp b/native/client_handler.cpp index 9b5567fc..20ce353c 100644 --- a/native/client_handler.cpp +++ b/native/client_handler.cpp @@ -15,6 +15,7 @@ #include "context_menu_handler.h" #include "dialog_handler.h" #include "display_handler.h" +#include "audio_handler.h" #include "download_handler.h" #include "drag_handler.h" #include "focus_handler.h" @@ -105,6 +106,10 @@ CefRefPtr ClientHandler::GetDisplayHandler() { return GetHandler("DisplayHandler"); } +CefRefPtr ClientHandler::GetAudioHandler() { + return GetHandler("AudioHandler"); +} + CefRefPtr ClientHandler::GetDownloadHandler() { return GetHandler("DownloadHandler"); } From cdca73f3db40c020a938dba47c659765066dffaa Mon Sep 17 00:00:00 2001 From: GiantLuigi4 <49770992+GiantLuigi4@users.noreply.github.com> Date: Fri, 22 Sep 2023 22:51:27 -0400 Subject: [PATCH 63/75] forgot to rename some stuff --- native/audio_handler.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/native/audio_handler.h b/native/audio_handler.h index dfe25097..9abd9c1f 100644 --- a/native/audio_handler.h +++ b/native/audio_handler.h @@ -2,8 +2,8 @@ // reserved. Use of this source code is governed by a BSD-style license that // can be found in the LICENSE file. -#ifndef JCEF_NATIVE_DISPLAY_HANDLER_H_ -#define JCEF_NATIVE_DISPLAY_HANDLER_H_ +#ifndef JCEF_NATIVE_AUDIO_HANDLER_H_ +#define JCEF_NATIVE_AUDIO_HANDLER_H_ #pragma once #include @@ -12,12 +12,12 @@ #include "jni_scoped_helpers.h" -// DisplayHandler implementation. +// AudioHandler implementation. class AudioHandler : public CefAudioHandler { public: AudioHandler(JNIEnv* env, jobject handler); - // CefDisplayHandler methods: + // CefAudioHandler methods: int GetAudioParameters(CefRefPtr browser, cef_audio_parameters_t params) override; void OnAudioStreamStarted(CefRefPtr browser, @@ -33,4 +33,4 @@ class AudioHandler : public CefAudioHandler { IMPLEMENT_REFCOUNTING(AudioHandler); }; -#endif // JCEF_NATIVE_DISPLAY_HANDLER_H_ +#endif // JCEF_NATIVE_AUDIO_HANDLER_H_ From e65c8d43257a7561f3f097ddb89ec5c1c4d006fe Mon Sep 17 00:00:00 2001 From: GiantLuigi4 <49770992+GiantLuigi4@users.noreply.github.com> Date: Fri, 22 Sep 2023 22:58:10 -0400 Subject: [PATCH 64/75] just realized I should add this comment ASAP --- native/audio_handler.h | 1 + 1 file changed, 1 insertion(+) diff --git a/native/audio_handler.h b/native/audio_handler.h index 9abd9c1f..f1fa58c9 100644 --- a/native/audio_handler.h +++ b/native/audio_handler.h @@ -12,6 +12,7 @@ #include "jni_scoped_helpers.h" +// https://github.com/chromiumembedded/cef/blob/master/include/capi/cef_audio_handler_capi.h // AudioHandler implementation. class AudioHandler : public CefAudioHandler { public: From 73dad8dd7ddc6eda6f15b060fc9738c1bc00b6b5 Mon Sep 17 00:00:00 2001 From: GiantLuigi4 <49770992+GiantLuigi4@users.noreply.github.com> Date: Fri, 22 Sep 2023 23:35:32 -0400 Subject: [PATCH 65/75] close to building... unsure what on earth to do about this last error? --- native/audio_handler.cpp | 8 ++++---- native/audio_handler.h | 14 +++++++------- native/client_handler.h | 1 + 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/native/audio_handler.cpp b/native/audio_handler.cpp index db6ee274..fe780028 100644 --- a/native/audio_handler.cpp +++ b/native/audio_handler.cpp @@ -9,8 +9,8 @@ AudioHandler::AudioHandler(JNIEnv* env, jobject handler) : handle_(env, handler) {} -int AudioHandler::GetAudioParameters(CefRefPtr browser, - cef_audio_parameters_t* params) { +bool AudioHandler::GetAudioParameters(CefRefPtr browser, + CefAudioParameters& params) { ScopedJNIEnv env; if (!env) return 0; @@ -23,7 +23,7 @@ int AudioHandler::GetAudioParameters(CefRefPtr browser, } void AudioHandler::OnAudioStreamStarted(CefRefPtr browser, - cef_audio_parameters_t params, int channels) { + const CefAudioParameters& params, int channels) { ScopedJNIEnv env; if (!env) return; @@ -35,7 +35,7 @@ void AudioHandler::OnAudioStreamStarted(CefRefPtr browser, jbrowser.get(), nullptr, channels); } -void AudioHandler::OnAudioStreamPacket(CefRefPtr browser, float** data, int frames, long long pts) { +void AudioHandler::OnAudioStreamPacket(CefRefPtr browser, const float** data, int frames, int64_t pts) { ScopedJNIEnv env; if (!env) return false; diff --git a/native/audio_handler.h b/native/audio_handler.h index f1fa58c9..7df6c7ed 100644 --- a/native/audio_handler.h +++ b/native/audio_handler.h @@ -8,24 +8,24 @@ #include -#include "include/cef_audio_handler_capi.h" +#include "include/cef_audio_handler.h" #include "jni_scoped_helpers.h" -// https://github.com/chromiumembedded/cef/blob/master/include/capi/cef_audio_handler_capi.h +// https://github.com/chromiumembedded/cef/blob/master/include/cef_audio_handler.h // AudioHandler implementation. class AudioHandler : public CefAudioHandler { public: AudioHandler(JNIEnv* env, jobject handler); // CefAudioHandler methods: - int GetAudioParameters(CefRefPtr browser, - cef_audio_parameters_t params) override; + bool GetAudioParameters(CefRefPtr browser, + CefAudioParameters& params) override; void OnAudioStreamStarted(CefRefPtr browser, - cef_audio_parameters_t params, int channels) override; - bool OnAudioStreamPacket(CefRefPtr browser, float** data, int frames, long long pts) override; + const CefAudioParameters& params, int channels) override; + void OnAudioStreamPacket(CefRefPtr browser, const float** data, int frames, int64_t pts) override; void OnAudioStreamStopped(CefRefPtr browser) override; - void OnAudioStreamError(CefRefPtr browser, CefString& text) override; + void OnAudioStreamError(CefRefPtr browser, const CefString& text) override; protected: ScopedJNIObjectGlobal handle_; diff --git a/native/client_handler.h b/native/client_handler.h index db285828..5c59a041 100644 --- a/native/client_handler.h +++ b/native/client_handler.h @@ -27,6 +27,7 @@ class ClientHandler : public CefClient { CefRefPtr GetContextMenuHandler() override; CefRefPtr GetDialogHandler() override; CefRefPtr GetDisplayHandler() override; + CefRefPtr GetAudioHandler() override; CefRefPtr GetDownloadHandler() override; CefRefPtr GetDragHandler() override; CefRefPtr GetFocusHandler() override; From a328fb2c02ff38cffa08b2936df47f4363bacff5 Mon Sep 17 00:00:00 2001 From: GiantLuigi4 <49770992+GiantLuigi4@users.noreply.github.com> Date: Fri, 22 Sep 2023 23:49:30 -0400 Subject: [PATCH 66/75] jcef native builds! --- java/org/cef/handler/CefAudioHandler.java | 2 +- .../cef/handler/CefAudioHandlerAdapter.java | 4 +-- native/CMakeLists.txt | 2 ++ native/audio_handler.cpp | 27 ++++++++++--------- native/client_handler.cpp | 6 ++--- 5 files changed, 23 insertions(+), 18 deletions(-) diff --git a/java/org/cef/handler/CefAudioHandler.java b/java/org/cef/handler/CefAudioHandler.java index fc07fbb4..707be515 100644 --- a/java/org/cef/handler/CefAudioHandler.java +++ b/java/org/cef/handler/CefAudioHandler.java @@ -11,7 +11,7 @@ * The methods of this class will be called on the UI thread. */ public interface CefAudioHandler { - int getAudioParameters(CefBrowser browser, Object params); + boolean getAudioParameters(CefBrowser browser, Object params); void onAudioStreamStarted(CefBrowser browser, Object params, int channels); diff --git a/java/org/cef/handler/CefAudioHandlerAdapter.java b/java/org/cef/handler/CefAudioHandlerAdapter.java index c9f96edb..69794099 100644 --- a/java/org/cef/handler/CefAudioHandlerAdapter.java +++ b/java/org/cef/handler/CefAudioHandlerAdapter.java @@ -11,8 +11,8 @@ * The methods of this class will be called on the UI thread. */ public abstract class CefAudioHandlerAdapter implements CefAudioHandler { - public int getAudioParameters(CefBrowser browser, Object params) { - return 0; // TODO + public boolean getAudioParameters(CefBrowser browser, Object params) { + return true; // TODO do I need something here? } public void onAudioStreamStarted(CefBrowser browser, Object params, int channels) { diff --git a/native/CMakeLists.txt b/native/CMakeLists.txt index 6147d448..93bcad1f 100644 --- a/native/CMakeLists.txt +++ b/native/CMakeLists.txt @@ -87,6 +87,8 @@ set(JCEF_SRCS dialog_handler.h display_handler.cpp display_handler.h + audio_handler.cpp + audio_handler.h download_handler.cpp download_handler.h drag_handler.cpp diff --git a/native/audio_handler.cpp b/native/audio_handler.cpp index fe780028..617ab88e 100644 --- a/native/audio_handler.cpp +++ b/native/audio_handler.cpp @@ -13,13 +13,17 @@ bool AudioHandler::GetAudioParameters(CefRefPtr browser, CefAudioParameters& params) { ScopedJNIEnv env; if (!env) - return 0; + return true; ScopedJNIBrowser jbrowser(env, browser); - return JNI_CALL_INT_METHOD(env, handle_, "getAudioParameters", - "(Lorg/cef/browser/CefBrowser;Ljava/lang/Object;)I", - jbrowser.get(), nullptr); + jboolean jreturn = JNI_FALSE; + + JNI_CALL_METHOD(env, handle_, "getAudioParameters", + "(Lorg/cef/browser/CefBrowser;Ljava/lang/Object;)Z", Boolean, + jreturn, jbrowser.get(), nullptr); + + return (jreturn != JNI_FALSE); } void AudioHandler::OnAudioStreamStarted(CefRefPtr browser, @@ -38,16 +42,15 @@ void AudioHandler::OnAudioStreamStarted(CefRefPtr browser, void AudioHandler::OnAudioStreamPacket(CefRefPtr browser, const float** data, int frames, int64_t pts) { ScopedJNIEnv env; if (!env) - return false; + return; ScopedJNIBrowser jbrowser(env, browser); - ScopedJNIString jtext(env, text); - jboolean jreturn = JNI_FALSE; + // ScopedJNIString jtext(env, text); // TODO: this is based on a bit of an assumption - JNI_CALL_METHOD(env, handle_, "onAudioStreamPacket", - "(Lorg/cef/browser/CefBrowser;Ljava/lang/String;[[FIL]])Z", Boolean, - jreturn, jbrowser.get(), jtext.get()); // TODO: + JNI_CALL_VOID_METHOD(env, handle_, "onAudioStreamPacket", + "(Lorg/cef/browser/CefBrowser;Ljava/lang/String;[[FIL]])V", + jbrowser.get(), nullptr, frames, (long long) pts); // TODO: } void AudioHandler::OnAudioStreamStopped(CefRefPtr browser) { @@ -66,12 +69,12 @@ void AudioHandler::OnAudioStreamError(CefRefPtr browser, const CefString& text) { ScopedJNIEnv env; if (!env) - return false; + return; ScopedJNIBrowser jbrowser(env, browser); ScopedJNIString jtext(env, text); JNI_CALL_VOID_METHOD(env, handle_, "onAudioStreamError", "(Lorg/cef/browser/CefBrowser;Ljava/lang/String;)V", - jbrowser.get(), text.get()); + jbrowser.get(), jtext.get()); } diff --git a/native/client_handler.cpp b/native/client_handler.cpp index 20ce353c..0318767e 100644 --- a/native/client_handler.cpp +++ b/native/client_handler.cpp @@ -106,9 +106,9 @@ CefRefPtr ClientHandler::GetDisplayHandler() { return GetHandler("DisplayHandler"); } -CefRefPtr ClientHandler::GetAudioHandler() { - return GetHandler("AudioHandler"); -} + CefRefPtr ClientHandler::GetAudioHandler() { + return GetHandler("AudioHandler"); + } CefRefPtr ClientHandler::GetDownloadHandler() { return GetHandler("DownloadHandler"); From fed8745a46810e75118f6e1e0f1d80328b9b4cb3 Mon Sep 17 00:00:00 2001 From: GiantLuigi4 <49770992+GiantLuigi4@users.noreply.github.com> Date: Sat, 23 Sep 2023 00:01:48 -0400 Subject: [PATCH 67/75] switch this to float[] instead of float[][] --- java/org/cef/handler/CefAudioHandlerAdapter.java | 2 +- native/audio_handler.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/java/org/cef/handler/CefAudioHandlerAdapter.java b/java/org/cef/handler/CefAudioHandlerAdapter.java index 69794099..e7d8713d 100644 --- a/java/org/cef/handler/CefAudioHandlerAdapter.java +++ b/java/org/cef/handler/CefAudioHandlerAdapter.java @@ -18,7 +18,7 @@ public boolean getAudioParameters(CefBrowser browser, Object params) { public void onAudioStreamStarted(CefBrowser browser, Object params, int channels) { } - public void onAudioStreamPacket(CefBrowser browser, float[][] data, int frames, long pts) { + public void onAudioStreamPacket(CefBrowser browser, float[] data, int frames, long pts) { } public void onAudioStreamStopped(CefBrowser browser) { diff --git a/native/audio_handler.cpp b/native/audio_handler.cpp index 617ab88e..5f25c426 100644 --- a/native/audio_handler.cpp +++ b/native/audio_handler.cpp @@ -49,7 +49,7 @@ void AudioHandler::OnAudioStreamPacket(CefRefPtr browser, const floa // TODO: this is based on a bit of an assumption JNI_CALL_VOID_METHOD(env, handle_, "onAudioStreamPacket", - "(Lorg/cef/browser/CefBrowser;Ljava/lang/String;[[FIL]])V", + "(Lorg/cef/browser/CefBrowser;Ljava/lang/String;[FIL)V", jbrowser.get(), nullptr, frames, (long long) pts); // TODO: } From e1e37d1f3b1381775c0c064ea514e1cd1b495824 Mon Sep 17 00:00:00 2001 From: GiantLuigi4 <49770992+GiantLuigi4@users.noreply.github.com> Date: Sat, 23 Sep 2023 23:54:08 -0400 Subject: [PATCH 68/75] getting close -- got an issue with onAudioStreamPacket and need to make bindings for CefAudioParameters --- java/org/cef/CefClient.java | 29 ++++++++++++++++------ java/org/cef/handler/CefAudioHandler.java | 2 +- java/org/cef/handler/CefClientHandler.java | 9 ++++++- native/audio_handler.cpp | 12 +++++++-- 4 files changed, 41 insertions(+), 11 deletions(-) diff --git a/java/org/cef/CefClient.java b/java/org/cef/CefClient.java index 3025e061..27984bdb 100644 --- a/java/org/cef/CefClient.java +++ b/java/org/cef/CefClient.java @@ -54,6 +54,7 @@ public class CefClient extends CefClientHandler private CefContextMenuHandler contextMenuHandler_ = null; private CefDialogHandler dialogHandler_ = null; private CefDisplayHandler displayHandler_ = null; + private CefAudioHandler audioHandler_ = null; private CefDownloadHandler downloadHandler_ = null; private CefDragHandler dragHandler_ = null; private CefFocusHandler focusHandler_ = null; @@ -123,6 +124,11 @@ protected CefDialogHandler getDialogHandler() { protected CefDisplayHandler getDisplayHandler() { return this; } + + @Override + protected CefAudioHandler getAudioHandler() { + return this; + } @Override protected CefDownloadHandler getDownloadHandler() { @@ -795,29 +801,38 @@ public boolean getScreenInfo(CefBrowser arg0, CefScreenInfo arg1) { // CefAudioHandler + public CefClient addAudioHandler(CefAudioHandler handler) { + if (audioHandler_ == null) audioHandler_ = handler; + return this; + } + + public void removeAudioHandler() { + audioHandler_ = null; + } @Override - public int getAudioParameters(CefBrowser browser, Object params) { - return 0; // TODO + public boolean getAudioParameters(CefBrowser browser, Object params) { + if (audioHandler_ != null) return audioHandler_.getAudioParameters(browser, params); + return false; } @Override public void onAudioStreamStarted(CefBrowser browser, Object params, int channels) { - // TODO + if (audioHandler_ != null) audioHandler_.onAudioStreamStarted(browser, params, channels); } @Override - public void onAudioStreamPacket(CefBrowser browser, float[][] data, int frames, long pts) { - // TODO + public void onAudioStreamPacket(CefBrowser browser, float[] data, int frames, long pts) { + if (audioHandler_ != null) audioHandler_.onAudioStreamPacket(browser, data, frames, pts); } @Override public void onAudioStreamStopped(CefBrowser browser) { - // TODO + if (audioHandler_ != null) audioHandler_.onAudioStreamStopped(browser); } @Override public void onAudioStreamError(CefBrowser browser, String text) { - // TODO + if (audioHandler_ != null) audioHandler_.onAudioStreamError(browser, text); } } diff --git a/java/org/cef/handler/CefAudioHandler.java b/java/org/cef/handler/CefAudioHandler.java index 707be515..46e40a21 100644 --- a/java/org/cef/handler/CefAudioHandler.java +++ b/java/org/cef/handler/CefAudioHandler.java @@ -15,7 +15,7 @@ public interface CefAudioHandler { void onAudioStreamStarted(CefBrowser browser, Object params, int channels); - void onAudioStreamPacket(CefBrowser browser, float[][] data, int frames, long pts); + void onAudioStreamPacket(CefBrowser browser, float[] data, int frames, long pts); void onAudioStreamStopped(CefBrowser browser); diff --git a/java/org/cef/handler/CefClientHandler.java b/java/org/cef/handler/CefClientHandler.java index 916af719..d819e6cf 100644 --- a/java/org/cef/handler/CefClientHandler.java +++ b/java/org/cef/handler/CefClientHandler.java @@ -80,13 +80,20 @@ protected void dispose() { * default implementation will be used. */ abstract protected CefDialogHandler getDialogHandler(); - + /** * Return the handler for browser display state events. * This method is a callback method and is called by * the native code. */ abstract protected CefDisplayHandler getDisplayHandler(); + + /** + * Return the handler for browser audio events. + * This method is a callback method and is called by + * the native code. + */ + abstract protected CefAudioHandler getAudioHandler(); /** * Return the handler for download events. diff --git a/native/audio_handler.cpp b/native/audio_handler.cpp index 5f25c426..d79d4fb9 100644 --- a/native/audio_handler.cpp +++ b/native/audio_handler.cpp @@ -47,10 +47,18 @@ void AudioHandler::OnAudioStreamPacket(CefRefPtr browser, const floa ScopedJNIBrowser jbrowser(env, browser); // ScopedJNIString jtext(env, text); + jfloatArray jArray = env->NewFloatArray(frames); + int size = frames; + jfloat* fill = (jfloat*) malloc(size * sizeof(jfloat)); + for (int i = 0; i < size; i++) { + fill[i] = data[0][i]; + } + env->SetFloatArrayRegion(jArray, 0, size, fill); + // TODO: this is based on a bit of an assumption JNI_CALL_VOID_METHOD(env, handle_, "onAudioStreamPacket", - "(Lorg/cef/browser/CefBrowser;Ljava/lang/String;[FIL)V", - jbrowser.get(), nullptr, frames, (long long) pts); // TODO: + "(Lorg/cef/browser/CefBrowser;[FIL)V", + jbrowser.get(), jArray, frames, (long long) pts); // TODO: } void AudioHandler::OnAudioStreamStopped(CefRefPtr browser) { From 99ec48a5fb29dd1999e5a6c261c9f72a4ce348a6 Mon Sep 17 00:00:00 2001 From: GiantLuigi4 <49770992+GiantLuigi4@users.noreply.github.com> Date: Sun, 24 Sep 2023 16:33:06 -0400 Subject: [PATCH 69/75] it's close, just need bindings for CefAudioParameters I believe --- native/audio_handler.cpp | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/native/audio_handler.cpp b/native/audio_handler.cpp index d79d4fb9..9efb8975 100644 --- a/native/audio_handler.cpp +++ b/native/audio_handler.cpp @@ -45,20 +45,18 @@ void AudioHandler::OnAudioStreamPacket(CefRefPtr browser, const floa return; ScopedJNIBrowser jbrowser(env, browser); - // ScopedJNIString jtext(env, text); + // TODO: this should truthfully be using a float buffer, but I'm not yet sure how to do that from JNI jfloatArray jArray = env->NewFloatArray(frames); int size = frames; jfloat* fill = (jfloat*) malloc(size * sizeof(jfloat)); - for (int i = 0; i < size; i++) { + for (int i = 0; i < size; i++) fill[i] = data[0][i]; - } - env->SetFloatArrayRegion(jArray, 0, size, fill); + env->SetFloatArrayRegion(jArray, 0, size, fill); - // TODO: this is based on a bit of an assumption JNI_CALL_VOID_METHOD(env, handle_, "onAudioStreamPacket", - "(Lorg/cef/browser/CefBrowser;[FIL)V", - jbrowser.get(), jArray, frames, (long long) pts); // TODO: + "(Lorg/cef/browser/CefBrowser;[FIJ)V", + jbrowser.get(), jArray, frames, (long long) pts); } void AudioHandler::OnAudioStreamStopped(CefRefPtr browser) { From 110abb6a71e20b8fbc2a0748823913518e810266 Mon Sep 17 00:00:00 2001 From: GiantLuigi4 <49770992+GiantLuigi4@users.noreply.github.com> Date: Sun, 24 Sep 2023 22:04:25 -0400 Subject: [PATCH 70/75] audio handler complete I think --- java/org/cef/CefClient.java | 5 +- java/org/cef/handler/CefAudioHandler.java | 5 +- .../cef/handler/CefAudioHandlerAdapter.java | 5 +- java/org/cef/misc/CefAudioParameters.java | 13 ++ java/org/cef/misc/CefChannelLayout.java | 129 ++++++++++++++++++ native/audio_handler.cpp | 38 +++++- 6 files changed, 185 insertions(+), 10 deletions(-) create mode 100644 java/org/cef/misc/CefAudioParameters.java create mode 100644 java/org/cef/misc/CefChannelLayout.java diff --git a/java/org/cef/CefClient.java b/java/org/cef/CefClient.java index 27984bdb..56ff52f8 100644 --- a/java/org/cef/CefClient.java +++ b/java/org/cef/CefClient.java @@ -23,6 +23,7 @@ import org.cef.callback.CefPrintJobCallback; import org.cef.handler.*; import org.cef.misc.BoolRef; +import org.cef.misc.CefAudioParameters; import org.cef.misc.CefPrintSettings; import org.cef.misc.StringRef; import org.cef.network.CefRequest; @@ -811,13 +812,13 @@ public void removeAudioHandler() { } @Override - public boolean getAudioParameters(CefBrowser browser, Object params) { + public boolean getAudioParameters(CefBrowser browser, CefAudioParameters params) { if (audioHandler_ != null) return audioHandler_.getAudioParameters(browser, params); return false; } @Override - public void onAudioStreamStarted(CefBrowser browser, Object params, int channels) { + public void onAudioStreamStarted(CefBrowser browser, CefAudioParameters params, int channels) { if (audioHandler_ != null) audioHandler_.onAudioStreamStarted(browser, params, channels); } diff --git a/java/org/cef/handler/CefAudioHandler.java b/java/org/cef/handler/CefAudioHandler.java index 46e40a21..79fda7cf 100644 --- a/java/org/cef/handler/CefAudioHandler.java +++ b/java/org/cef/handler/CefAudioHandler.java @@ -5,15 +5,16 @@ package org.cef.handler; import org.cef.browser.CefBrowser; +import org.cef.misc.CefAudioParameters; /** * Implement this interface to handle events related to audio playing. * The methods of this class will be called on the UI thread. */ public interface CefAudioHandler { - boolean getAudioParameters(CefBrowser browser, Object params); + boolean getAudioParameters(CefBrowser browser, CefAudioParameters params); - void onAudioStreamStarted(CefBrowser browser, Object params, int channels); + void onAudioStreamStarted(CefBrowser browser, CefAudioParameters params, int channels); void onAudioStreamPacket(CefBrowser browser, float[] data, int frames, long pts); diff --git a/java/org/cef/handler/CefAudioHandlerAdapter.java b/java/org/cef/handler/CefAudioHandlerAdapter.java index e7d8713d..31224635 100644 --- a/java/org/cef/handler/CefAudioHandlerAdapter.java +++ b/java/org/cef/handler/CefAudioHandlerAdapter.java @@ -5,17 +5,18 @@ package org.cef.handler; import org.cef.browser.CefBrowser; +import org.cef.misc.CefAudioParameters; /** * Implement this interface to handle events related to audio playing. * The methods of this class will be called on the UI thread. */ public abstract class CefAudioHandlerAdapter implements CefAudioHandler { - public boolean getAudioParameters(CefBrowser browser, Object params) { + public boolean getAudioParameters(CefBrowser browser, CefAudioParameters params) { return true; // TODO do I need something here? } - public void onAudioStreamStarted(CefBrowser browser, Object params, int channels) { + public void onAudioStreamStarted(CefBrowser browser, CefAudioParameters params, int channels) { } public void onAudioStreamPacket(CefBrowser browser, float[] data, int frames, long pts) { diff --git a/java/org/cef/misc/CefAudioParameters.java b/java/org/cef/misc/CefAudioParameters.java new file mode 100644 index 00000000..87b65776 --- /dev/null +++ b/java/org/cef/misc/CefAudioParameters.java @@ -0,0 +1,13 @@ +package org.cef.misc; + +public class CefAudioParameters { + public final CefChannelLayout channelLayout; + public final int sampleRate; + public final int framesPerBuffer; + + public CefAudioParameters(CefChannelLayout channelLayout, int sampleRate, int framesPerBuffer) { + this.channelLayout = channelLayout; + this.sampleRate = sampleRate; + this.framesPerBuffer = framesPerBuffer; + } +} diff --git a/java/org/cef/misc/CefChannelLayout.java b/java/org/cef/misc/CefChannelLayout.java new file mode 100644 index 00000000..9d45c798 --- /dev/null +++ b/java/org/cef/misc/CefChannelLayout.java @@ -0,0 +1,129 @@ +package org.cef.misc; + +// https://cef-builds.spotifycdn.com/docs/109.1/cef__types_8h.html#adb8605711e30e1aec6031029c94e7904 +public enum CefChannelLayout { + CEF_CHANNEL_LAYOUT_NONE(0), + + CEF_CHANNEL_LAYOUT_UNSUPPORTED(1), + + /// Front C + CEF_CHANNEL_LAYOUT_MONO(2), + + /// Front L, Front R + CEF_CHANNEL_LAYOUT_STEREO(3), + + /// Front L, Front R, Back C + CEF_CHANNEL_LAYOUT_2_1(4), + + /// Front L, Front R, Front C + CEF_CHANNEL_LAYOUT_SURROUND(5), + + /// Front L, Front R, Front C, Back C + CEF_CHANNEL_LAYOUT_4_0(6), + + /// Front L, Front R, Side L, Side R + CEF_CHANNEL_LAYOUT_2_2(7), + + /// Front L, Front R, Back L, Back R + CEF_CHANNEL_LAYOUT_QUAD(8), + + /// Front L, Front R, Front C, Side L, Side R + CEF_CHANNEL_LAYOUT_5_0(9), + + /// Front L, Front R, Front C, LFE, Side L, Side R + CEF_CHANNEL_LAYOUT_5_1(10), + + /// Front L, Front R, Front C, Back L, Back R + CEF_CHANNEL_LAYOUT_5_0_BACK(11), + + /// Front L, Front R, Front C, LFE, Back L, Back R + CEF_CHANNEL_LAYOUT_5_1_BACK(12), + + /// Front L, Front R, Front C, Side L, Side R, Back L, Back R + CEF_CHANNEL_LAYOUT_7_0(13), + + /// Front L, Front R, Front C, LFE, Side L, Side R, Back L, Back R + CEF_CHANNEL_LAYOUT_7_1(14), + + /// Front L, Front R, Front C, LFE, Side L, Side R, Front LofC, Front RofC + CEF_CHANNEL_LAYOUT_7_1_WIDE(15), + + /// Stereo L, Stereo R + CEF_CHANNEL_LAYOUT_STEREO_DOWNMIX(16), + + /// Stereo L, Stereo R, LFE + CEF_CHANNEL_LAYOUT_2POINT1(17), + + /// Stereo L, Stereo R, Front C, LFE + CEF_CHANNEL_LAYOUT_3_1(18), + + /// Stereo L, Stereo R, Front C, Rear C, LFE + CEF_CHANNEL_LAYOUT_4_1(19), + + /// Stereo L, Stereo R, Front C, Side L, Side R, Back C + CEF_CHANNEL_LAYOUT_6_0(20), + + /// Stereo L, Stereo R, Side L, Side R, Front LofC, Front RofC + CEF_CHANNEL_LAYOUT_6_0_FRONT(21), + + /// Stereo L, Stereo R, Front C, Rear L, Rear R, Rear C + CEF_CHANNEL_LAYOUT_HEXAGONAL(22), + + /// Stereo L, Stereo R, Front C, LFE, Side L, Side R, Rear Center + CEF_CHANNEL_LAYOUT_6_1(23), + + /// Stereo L, Stereo R, Front C, LFE, Back L, Back R, Rear Center + CEF_CHANNEL_LAYOUT_6_1_BACK(24), + + /// Stereo L, Stereo R, Side L, Side R, Front LofC, Front RofC, LFE + CEF_CHANNEL_LAYOUT_6_1_FRONT(25), + + /// Front L, Front R, Front C, Side L, Side R, Front LofC, Front RofC + CEF_CHANNEL_LAYOUT_7_0_FRONT(26), + + /// Front L, Front R, Front C, LFE, Back L, Back R, Front LofC, Front RofC + CEF_CHANNEL_LAYOUT_7_1_WIDE_BACK(27), + + /// Front L, Front R, Front C, Side L, Side R, Rear L, Back R, Back C. + CEF_CHANNEL_LAYOUT_OCTAGONAL(28), + + /// Channels are not explicitly mapped to speakers. + CEF_CHANNEL_LAYOUT_DISCRETE(29), + + /// Front L, Front R, Front C. Front C contains the keyboard mic audio. This + /// layout is only intended for input for WebRTC. The Front C channel + /// is stripped away in the WebRTC audio input pipeline and never seen outside + /// of that. + CEF_CHANNEL_LAYOUT_STEREO_AND_KEYBOARD_MIC(30), + + /// Front L, Front R, Side L, Side R, LFE + CEF_CHANNEL_LAYOUT_4_1_QUAD_SIDE(31), + + /// Actual channel layout is specified in the bitstream and the actual channel + /// count is unknown at Chromium media pipeline level (useful for audio + /// pass-through mode). + CEF_CHANNEL_LAYOUT_BITSTREAM(32), + + /// Front L, Front R, Front C, LFE, Side L, Side R, + /// Front Height L, Front Height R, Rear Height L, Rear Height R + /// Will be represented as six channels (5.1) due to eight channel limit + /// kMaxConcurrentChannels + CEF_CHANNEL_LAYOUT_5_1_4_DOWNMIX(33), + + /// Max value, must always equal the largest entry ever logged. + CEF_CHANNEL_LAYOUT_MAX(33); + + private final int id; + + CefChannelLayout(int id) { + this.id = id; + } + + // micro optimization: values() creates a new array every time it's called + // having this static final array allows me to not have to create that array more than once + private static final CefChannelLayout[] LAYOUTS = CefChannelLayout.values(); + + public static CefChannelLayout forId(int id) { + return LAYOUTS[id]; + } +} diff --git a/native/audio_handler.cpp b/native/audio_handler.cpp index 9efb8975..db12e020 100644 --- a/native/audio_handler.cpp +++ b/native/audio_handler.cpp @@ -6,9 +6,39 @@ #include "jni_util.h" +//#include + AudioHandler::AudioHandler(JNIEnv* env, jobject handler) : handle_(env, handler) {} +jobject jniParams(ScopedJNIEnv env, CefAudioParameters& params) { + jclass cls = env->FindClass("org/cef/misc/CefChannelLayout"); + if (cls == nullptr) { +// std::cout << "Could not find class 0"; + return nullptr; + } + jmethodID getLayout = env->GetStaticMethodID(cls, "forId", "(I)Lorg/cef/misc/CefChannelLayout;"); + if (getLayout == 0) { +// std::cout << "Could not find method 0"; + return nullptr; + } + jobject layout = env->CallStaticObjectMethod(cls, getLayout, (int) params.channel_layout); + + cls = env->FindClass("org/cef/misc/CefAudioParameters"); + if (cls == nullptr) { +// std::cout << "Could not find class 1"; + return nullptr; + } + jmethodID constructor = env->GetMethodID(cls, "", "(Lorg/cef/misc/CefChannelLayout;II)V"); + if (constructor == 0) { +// std::cout << "Could not find constructor 1"; + return nullptr; + } + jobject parameters = env->NewObject(cls, constructor, layout, params.sample_rate, params.frames_per_buffer); + + return parameters; +} + bool AudioHandler::GetAudioParameters(CefRefPtr browser, CefAudioParameters& params) { ScopedJNIEnv env; @@ -20,8 +50,8 @@ bool AudioHandler::GetAudioParameters(CefRefPtr browser, jboolean jreturn = JNI_FALSE; JNI_CALL_METHOD(env, handle_, "getAudioParameters", - "(Lorg/cef/browser/CefBrowser;Ljava/lang/Object;)Z", Boolean, - jreturn, jbrowser.get(), nullptr); + "(Lorg/cef/browser/CefBrowser;Lorg/cef/misc/CefAudioParameters;)Z", Boolean, + jreturn, jbrowser.get(), jniParams(env, params)); return (jreturn != JNI_FALSE); } @@ -35,8 +65,8 @@ void AudioHandler::OnAudioStreamStarted(CefRefPtr browser, ScopedJNIBrowser jbrowser(env, browser); JNI_CALL_VOID_METHOD(env, handle_, "onAudioStreamStarted", - "(Lorg/cef/browser/CefBrowser;Ljava/lang/Object;I)V", - jbrowser.get(), nullptr, channels); + "(Lorg/cef/browser/CefBrowser;Lorg/cef/misc/CefAudioParameters;I)V", + jbrowser.get(), jniParams(env, params), channels); } void AudioHandler::OnAudioStreamPacket(CefRefPtr browser, const float** data, int frames, int64_t pts) { From 21d088009553006d71ec6adaceaf1921a2d8268f Mon Sep 17 00:00:00 2001 From: ds58 <30220598+ds58@users.noreply.github.com> Date: Mon, 25 Sep 2023 20:01:41 -0500 Subject: [PATCH 71/75] Fix compile issue in audio_handler.cpp --- native/audio_handler.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/native/audio_handler.cpp b/native/audio_handler.cpp index db12e020..c54f5dc7 100644 --- a/native/audio_handler.cpp +++ b/native/audio_handler.cpp @@ -11,7 +11,7 @@ AudioHandler::AudioHandler(JNIEnv* env, jobject handler) : handle_(env, handler) {} -jobject jniParams(ScopedJNIEnv env, CefAudioParameters& params) { +jobject jniParams(ScopedJNIEnv env, const CefAudioParameters& params) { jclass cls = env->FindClass("org/cef/misc/CefChannelLayout"); if (cls == nullptr) { // std::cout << "Could not find class 0"; From 6a539d0d77dd6b74585678e13837bc436e14b890 Mon Sep 17 00:00:00 2001 From: GiantLuigi4 <49770992+GiantLuigi4@users.noreply.github.com> Date: Mon, 25 Sep 2023 22:46:05 -0400 Subject: [PATCH 72/75] getAudioParameters should return false by default also a little formatting in audio_handler.cpp, and temporarily switch the second arg of onAudioStream to nullptr --- java/org/cef/handler/CefAudioHandlerAdapter.java | 2 +- native/audio_handler.cpp | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/java/org/cef/handler/CefAudioHandlerAdapter.java b/java/org/cef/handler/CefAudioHandlerAdapter.java index 31224635..500e5c52 100644 --- a/java/org/cef/handler/CefAudioHandlerAdapter.java +++ b/java/org/cef/handler/CefAudioHandlerAdapter.java @@ -13,7 +13,7 @@ */ public abstract class CefAudioHandlerAdapter implements CefAudioHandler { public boolean getAudioParameters(CefBrowser browser, CefAudioParameters params) { - return true; // TODO do I need something here? + return false; } public void onAudioStreamStarted(CefBrowser browser, CefAudioParameters params, int channels) { diff --git a/native/audio_handler.cpp b/native/audio_handler.cpp index c54f5dc7..3e7a62b6 100644 --- a/native/audio_handler.cpp +++ b/native/audio_handler.cpp @@ -40,7 +40,7 @@ jobject jniParams(ScopedJNIEnv env, const CefAudioParameters& params) { } bool AudioHandler::GetAudioParameters(CefRefPtr browser, - CefAudioParameters& params) { + CefAudioParameters& params) { ScopedJNIEnv env; if (!env) return true; @@ -57,7 +57,7 @@ bool AudioHandler::GetAudioParameters(CefRefPtr browser, } void AudioHandler::OnAudioStreamStarted(CefRefPtr browser, - const CefAudioParameters& params, int channels) { + const CefAudioParameters& params, int channels) { ScopedJNIEnv env; if (!env) return; @@ -66,7 +66,7 @@ void AudioHandler::OnAudioStreamStarted(CefRefPtr browser, JNI_CALL_VOID_METHOD(env, handle_, "onAudioStreamStarted", "(Lorg/cef/browser/CefBrowser;Lorg/cef/misc/CefAudioParameters;I)V", - jbrowser.get(), jniParams(env, params), channels); + jbrowser.get(), nullptr, channels); } void AudioHandler::OnAudioStreamPacket(CefRefPtr browser, const float** data, int frames, int64_t pts) { From d5e3cece98755ff1e5af39261e6a486a5d9adb5d Mon Sep 17 00:00:00 2001 From: ds58 <30220598+ds58@users.noreply.github.com> Date: Tue, 31 Oct 2023 18:45:11 -0500 Subject: [PATCH 73/75] Add import, fix compile --- java/org/cef/browser/CefBrowserOsr.java | 1 + 1 file changed, 1 insertion(+) diff --git a/java/org/cef/browser/CefBrowserOsr.java b/java/org/cef/browser/CefBrowserOsr.java index 7bb51914..cd80d9ba 100644 --- a/java/org/cef/browser/CefBrowserOsr.java +++ b/java/org/cef/browser/CefBrowserOsr.java @@ -10,6 +10,7 @@ import org.cef.handler.CefScreenInfo; import java.awt.*; +import java.awt.dnd.DnDConstants; import java.awt.dnd.DragGestureRecognizer; import java.awt.dnd.DragSource; import java.awt.event.MouseEvent; From 76b3debdf2694d90d90808ad282b73506357d5f5 Mon Sep 17 00:00:00 2001 From: ds58 <30220598+ds58@users.noreply.github.com> Date: Fri, 4 Oct 2024 18:15:05 -0500 Subject: [PATCH 74/75] Update CEF branch to 6478 --- CMakeLists.txt | 6 +- java/org/cef/CefApp.java | 13 +- java/org/cef/CefBrowserSettings.java | 31 +++ java/org/cef/CefClient.java | 121 ++++++------ java/org/cef/CefSettings.java | 32 +++- java/org/cef/SystemBootstrap.java | 4 +- java/org/cef/browser/CefBrowser.java | 45 ++++- java/org/cef/browser/CefBrowserFactory.java | 5 +- java/org/cef/browser/CefBrowserOsr.java | 26 ++- java/org/cef/browser/CefBrowserWr.java | 0 java/org/cef/browser/CefBrowser_N.java | 114 ++++++++--- java/org/cef/browser/CefDevToolsClient.java | 165 ++++++++++++++++ .../browser/CefDevToolsMessageObserver.java | 34 ++++ java/org/cef/browser/CefFrame.java | 11 +- java/org/cef/browser/CefFrame_N.java | 15 +- java/org/cef/browser/CefPaintEvent.java | 51 +++++ java/org/cef/browser/CefRegistration.java | 24 +++ java/org/cef/browser/CefRegistration_N.java | 33 ++++ java/org/cef/handler/CefAppHandler.java | 19 ++ .../org/cef/handler/CefAppHandlerAdapter.java | 24 ++- java/org/cef/handler/CefDialogHandler.java | 8 +- java/org/cef/handler/CefDisplayHandler.java | 7 + .../cef/handler/CefDisplayHandlerAdapter.java | 5 + java/org/cef/handler/CefDownloadHandler.java | 10 +- .../handler/CefDownloadHandlerAdapter.java | 6 +- java/org/cef/handler/CefLoadHandler.java | 11 -- java/org/cef/handler/CefRenderHandler.java | 20 ++ java/org/cef/handler/CefRequestHandler.java | 9 +- .../cef/handler/CefRequestHandlerAdapter.java | 3 +- java/org/cef/misc/CefPdfPrintSettings.java | 12 ++ java/tests/detailed/MainFrame.java | 95 ++++++++-- .../tests/detailed/dialog/DownloadDialog.java | 4 +- .../detailed/handler/KeyboardHandler.java | 26 +++ .../detailed/handler/RequestHandler.java | 6 +- java/tests/detailed/ui/MenuBar.java | 61 +++++- java/tests/junittests/TestFrame.java | 3 +- java/tests/simple/MainFrame.java | 41 +++- native/CMakeLists.txt | 6 + native/CefBrowser_N.cpp | 177 +++++++++++++++--- native/CefBrowser_N.h | 73 +++++++- native/CefFileDialogCallback_N.h | 3 +- native/CefFrame_N.cpp | 17 +- native/CefFrame_N.h | 13 +- native/CefRegistration_N.cpp | 14 ++ native/CefRegistration_N.h | 21 +++ native/browser_process_handler.cpp | 25 +++ native/browser_process_handler.h | 2 + native/context.cpp | 5 + native/devtools_message_observer.cpp | 44 +++++ native/devtools_message_observer.h | 37 ++++ native/dialog_handler.cpp | 25 ++- native/dialog_handler.h | 2 + native/display_handler.cpp | 12 ++ native/display_handler.h | 2 + native/download_handler.cpp | 14 +- native/download_handler.h | 2 +- native/int_callback.cpp | 20 ++ native/int_callback.h | 28 +++ native/jni_util.cpp | 22 --- native/request_handler.cpp | 16 +- native/request_handler.h | 4 +- tools/make_all_jni_headers.bat | 1 + 62 files changed, 1431 insertions(+), 254 deletions(-) create mode 100644 java/org/cef/CefBrowserSettings.java create mode 100644 java/org/cef/browser/CefBrowserWr.java create mode 100644 java/org/cef/browser/CefDevToolsClient.java create mode 100644 java/org/cef/browser/CefDevToolsMessageObserver.java create mode 100644 java/org/cef/browser/CefPaintEvent.java create mode 100644 java/org/cef/browser/CefRegistration.java create mode 100644 java/org/cef/browser/CefRegistration_N.java create mode 100644 native/CefRegistration_N.cpp create mode 100644 native/CefRegistration_N.h create mode 100644 native/devtools_message_observer.cpp create mode 100644 native/devtools_message_observer.h create mode 100644 native/int_callback.cpp create mode 100644 native/int_callback.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 22d0fc06..d6b36e0f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -117,8 +117,6 @@ cmake_minimum_required(VERSION 3.19) # Only generate Debug and Release configuration types. set(CMAKE_CONFIGURATION_TYPES Debug Release) -set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded") - # Project name. project(jcef) @@ -132,12 +130,12 @@ set_property(GLOBAL PROPERTY OS_FOLDERS ON) # Specify the CEF branch if(NOT DEFINED CEF_BRANCH) - set(CEF_BRANCH "5845") + set(CEF_BRANCH "6478") endif() # Specify the CEF distribution version. if(NOT DEFINED CEF_VERSION) - set(CEF_VERSION "116.0.27+gd8c85ac+chromium-116.0.5845.190") + set(CEF_VERSION "126.2.19+ga5d51ba+chromium-126.0.6478.183") endif() # Determine the platform. diff --git a/java/org/cef/CefApp.java b/java/org/cef/CefApp.java index eff69e01..fb801003 100644 --- a/java/org/cef/CefApp.java +++ b/java/org/cef/CefApp.java @@ -8,17 +8,12 @@ import org.cef.handler.CefAppHandler; import org.cef.handler.CefAppHandlerAdapter; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; +import javax.swing.*; import java.io.File; -import java.io.FilenameFilter; import java.nio.file.Path; import java.nio.file.Paths; import java.util.HashSet; -import javax.swing.SwingUtilities; -import javax.swing.Timer; - /** * Exposes static methods for managing the global CEF context. */ @@ -102,6 +97,12 @@ public enum CefAppState { */ INITIALIZED, + /** + * CEF initialization has failed (for example due to a second process using + * the same root_cache_path). + */ + INITIALIZATION_FAILED, + /** * CefApp is in its shutdown process. All CefClients and CefBrowser * instances will be disposed. No new CefClient or CefBrowser is allowed to diff --git a/java/org/cef/CefBrowserSettings.java b/java/org/cef/CefBrowserSettings.java new file mode 100644 index 00000000..8733a418 --- /dev/null +++ b/java/org/cef/CefBrowserSettings.java @@ -0,0 +1,31 @@ +// Copyright (c) 2024 The Chromium Embedded Framework Authors. All rights +// reserved. Use of this source code is governed by a BSD-style license that +// can be found in the LICENSE file. + +package org.cef; + +/** + * Browser initialization settings. Specify NULL or 0 to get the recommended + * default values. The consequences of using custom values may not be well + * tested. Many of these and other settings can also configured using command- + * line switches. + */ +public class CefBrowserSettings { + /** + * The maximum rate in frames per second (fps) that CefRenderHandler::OnPaint + * will be called for a windowless browser. The actual fps may be lower if + * the browser cannot generate frames at the requested rate. The minimum + * value is 1 and the maximum value is 60 (default 30). This value can also + * be changed dynamically via {@code CefBrowser#setWindowlessFrameRate} + */ + public int windowless_frame_rate = 0; + + public CefBrowserSettings() {} + + @Override + public CefBrowserSettings clone() { + CefBrowserSettings tmp = new CefBrowserSettings(); + tmp.windowless_frame_rate = windowless_frame_rate; + return tmp; + } +} diff --git a/java/org/cef/CefClient.java b/java/org/cef/CefClient.java index cb3a58c7..40dd892c 100644 --- a/java/org/cef/CefClient.java +++ b/java/org/cef/CefClient.java @@ -4,44 +4,21 @@ package org.cef; -import org.cef.browser.CefBrowser; -import org.cef.browser.CefBrowserFactory; -import org.cef.browser.CefFrame; -import org.cef.browser.CefMessageRouter; -import org.cef.browser.CefRequestContext; -import org.cef.callback.CefAuthCallback; -import org.cef.callback.CefBeforeDownloadCallback; -import org.cef.callback.CefCallback; -import org.cef.callback.CefContextMenuParams; -import org.cef.callback.CefDownloadItem; -import org.cef.callback.CefDownloadItemCallback; -import org.cef.callback.CefDragData; -import org.cef.callback.CefFileDialogCallback; -import org.cef.callback.CefJSDialogCallback; -import org.cef.callback.CefMenuModel; -import org.cef.callback.CefPrintDialogCallback; -import org.cef.callback.CefPrintJobCallback; +import org.cef.browser.*; +import org.cef.callback.*; import org.cef.handler.*; import org.cef.misc.BoolRef; import org.cef.misc.CefAudioParameters; import org.cef.misc.CefPrintSettings; -import org.cef.misc.StringRef; import org.cef.network.CefRequest; import org.cef.network.CefRequest.TransitionType; -import org.cef.network.CefResponse; -import org.cef.network.CefURLRequest; - -import java.awt.Dimension; -import java.awt.Point; -import java.awt.Rectangle; -import java.beans.PropertyChangeEvent; -import java.beans.PropertyChangeListener; + +import java.awt.*; import java.nio.ByteBuffer; import java.util.Collection; import java.util.HashMap; import java.util.Vector; - -import javax.swing.SwingUtilities; +import java.util.function.Consumer; /** * Client that owns a browser and renderer. @@ -87,20 +64,20 @@ public void dispose() { public CefBrowser createBrowser( String url, boolean isTransparent) { - return createBrowser(url, isTransparent, null); + return createBrowser(url, isTransparent, null, null); } public CefBrowser createBrowser(String url, boolean isTransparent, - CefRequestContext context) { + CefRequestContext context, CefBrowserSettings settings) { if (isDisposed_) throw new IllegalStateException("Can't create browser. CefClient is disposed"); - return CefBrowserFactory.create(this, url, isTransparent, context); + return CefBrowserFactory.create(this, url, isTransparent, context, settings); } @Override protected CefBrowser getBrowser(int identifier) { synchronized (browser_) { - return browser_.get(new Integer(identifier)); + return browser_.get(identifier); } } @@ -125,7 +102,7 @@ protected CefDialogHandler getDialogHandler() { protected CefDisplayHandler getDisplayHandler() { return this; } - + @Override protected CefAudioHandler getAudioHandler() { return this; @@ -232,10 +209,11 @@ public void removeDialogHandler() { @Override public boolean onFileDialog(CefBrowser browser, FileDialogMode mode, String title, - String defaultFilePath, Vector acceptFilters, CefFileDialogCallback callback) { + String defaultFilePath, Vector acceptFilters, Vector acceptExtensions, + Vector acceptDescriptions, CefFileDialogCallback callback) { if (dialogHandler_ != null && browser != null) { - return dialogHandler_.onFileDialog( - browser, mode, title, defaultFilePath, acceptFilters, callback); + return dialogHandler_.onFileDialog(browser, mode, title, defaultFilePath, acceptFilters, + acceptExtensions, acceptDescriptions, callback); } return false; } @@ -263,6 +241,12 @@ public void onTitleChange(CefBrowser browser, String title) { displayHandler_.onTitleChange(browser, title); } + @Override + public void onFullscreenModeChange(CefBrowser browser, boolean fullscreen) { + if (displayHandler_ != null && browser != null) + displayHandler_.onFullscreenModeChange(browser, fullscreen); + } + @Override public boolean onTooltip(CefBrowser browser, String text) { if (displayHandler_ != null && browser != null) { @@ -317,10 +301,12 @@ public void removeDownloadHandler() { } @Override - public void onBeforeDownload(CefBrowser browser, CefDownloadItem downloadItem, - String suggestedName, CefBeforeDownloadCallback callback) { + public boolean onBeforeDownload(CefBrowser browser, CefDownloadItem downloadItem, + String suggestedName, CefBeforeDownloadCallback callback) { if (downloadHandler_ != null && browser != null) - downloadHandler_.onBeforeDownload(browser, downloadItem, suggestedName, callback); + return downloadHandler_.onBeforeDownload( + browser, downloadItem, suggestedName, callback); + return false; } @Override @@ -395,8 +381,8 @@ public void removeJSDialogHandler() { @Override public boolean onJSDialog(CefBrowser browser, String origin_url, JSDialogType dialog_type, - String message_text, String default_prompt_text, CefJSDialogCallback callback, - BoolRef suppress_message) { + String message_text, String default_prompt_text, CefJSDialogCallback callback, + BoolRef suppress_message) { if (jsDialogHandler_ != null && browser != null) return jsDialogHandler_.onJSDialog(browser, origin_url, dialog_type, message_text, default_prompt_text, callback, suppress_message); @@ -405,7 +391,7 @@ public boolean onJSDialog(CefBrowser browser, String origin_url, JSDialogType di @Override public boolean onBeforeUnloadDialog(CefBrowser browser, String message_text, boolean is_reload, - CefJSDialogCallback callback) { + CefJSDialogCallback callback) { if (jsDialogHandler_ != null && browser != null) return jsDialogHandler_.onBeforeUnloadDialog( browser, message_text, is_reload, callback); @@ -573,7 +559,7 @@ public void onLoadEnd(CefBrowser browser, CefFrame frame, int httpStatusCode) { @Override public void onLoadError(CefBrowser browser, CefFrame frame, ErrorCode errorCode, - String errorText, String failedUrl) { + String errorText, String failedUrl) { if (loadHandler_ != null && browser != null) loadHandler_.onLoadError(browser, frame, errorCode, errorText, failedUrl); } @@ -611,7 +597,7 @@ public boolean onPrintDialog( @Override public boolean onPrintJob(CefBrowser browser, String documentName, String pdfFilePath, - CefPrintJobCallback callback) { + CefPrintJobCallback callback) { if (printHandler_ != null && browser != null) return printHandler_.onPrintJob(browser, documentName, pdfFilePath, callback); return false; @@ -679,7 +665,7 @@ public void onPopupSize(CefBrowser browser, Rectangle size) { @Override public void onPaint(CefBrowser browser, boolean popup, Rectangle[] dirtyRects, - ByteBuffer buffer, int width, int height) { + ByteBuffer buffer, int width, int height) { if (browser == null) return; CefRenderHandler realHandler = browser.getRenderHandler(); @@ -687,6 +673,21 @@ public void onPaint(CefBrowser browser, boolean popup, Rectangle[] dirtyRects, realHandler.onPaint(browser, popup, dirtyRects, buffer, width, height); } + @Override + public void addOnPaintListener(Consumer listener) { + + } + + @Override + public void setOnPaintListener(Consumer listener) { + + } + + @Override + public void removeOnPaintListener(Consumer listener) { + + } + @Override public boolean startDragging(CefBrowser browser, CefDragData dragData, int mask, int x, int y) { if (browser == null) return false; @@ -717,7 +718,7 @@ public void removeRequestHandler() { @Override public boolean onBeforeBrowse(CefBrowser browser, CefFrame frame, CefRequest request, - boolean user_gesture, boolean is_redirect) { + boolean user_gesture, boolean is_redirect) { if (requestHandler_ != null && browser != null) return requestHandler_.onBeforeBrowse( browser, frame, request, user_gesture, is_redirect); @@ -735,8 +736,8 @@ public boolean onOpenURLFromTab( @Override public CefResourceRequestHandler getResourceRequestHandler(CefBrowser browser, CefFrame frame, - CefRequest request, boolean isNavigation, boolean isDownload, String requestInitiator, - BoolRef disableDefaultHandling) { + CefRequest request, boolean isNavigation, boolean isDownload, String requestInitiator, + BoolRef disableDefaultHandling) { if (requestHandler_ != null && browser != null) { return requestHandler_.getResourceRequestHandler(browser, frame, request, isNavigation, isDownload, requestInitiator, disableDefaultHandling); @@ -746,7 +747,7 @@ public CefResourceRequestHandler getResourceRequestHandler(CefBrowser browser, C @Override public boolean getAuthCredentials(CefBrowser browser, String origin_url, boolean isProxy, - String host, int port, String realm, String scheme, CefAuthCallback callback) { + String host, int port, String realm, String scheme, CefAuthCallback callback) { if (requestHandler_ != null && browser != null) return requestHandler_.getAuthCredentials( browser, origin_url, isProxy, host, port, realm, scheme, callback); @@ -762,8 +763,10 @@ public boolean onCertificateError( } @Override - public void onRenderProcessTerminated(CefBrowser browser, TerminationStatus status) { - if (requestHandler_ != null) requestHandler_.onRenderProcessTerminated(browser, status); + public void onRenderProcessTerminated( + CefBrowser browser, TerminationStatus status, int error_code, String error_string) { + if (requestHandler_ != null) + requestHandler_.onRenderProcessTerminated(browser, status, error_code, error_string); } // CefWindowHandler @@ -791,39 +794,39 @@ public void onMouseEvent( public boolean getScreenInfo(CefBrowser arg0, CefScreenInfo arg1) { return false; } - + // CefAudioHandler - + public CefClient addAudioHandler(CefAudioHandler handler) { if (audioHandler_ == null) audioHandler_ = handler; return this; } - + public void removeAudioHandler() { audioHandler_ = null; } - + @Override public boolean getAudioParameters(CefBrowser browser, CefAudioParameters params) { if (audioHandler_ != null) return audioHandler_.getAudioParameters(browser, params); return false; } - + @Override public void onAudioStreamStarted(CefBrowser browser, CefAudioParameters params, int channels) { if (audioHandler_ != null) audioHandler_.onAudioStreamStarted(browser, params, channels); } - + @Override public void onAudioStreamPacket(CefBrowser browser, float[] data, int frames, long pts) { if (audioHandler_ != null) audioHandler_.onAudioStreamPacket(browser, data, frames, pts); } - + @Override public void onAudioStreamStopped(CefBrowser browser) { if (audioHandler_ != null) audioHandler_.onAudioStreamStopped(browser); } - + @Override public void onAudioStreamError(CefBrowser browser, String text) { if (audioHandler_ != null) audioHandler_.onAudioStreamError(browser, text); diff --git a/java/org/cef/CefSettings.java b/java/org/cef/CefSettings.java index a094b355..49583d0a 100644 --- a/java/org/cef/CefSettings.java +++ b/java/org/cef/CefSettings.java @@ -106,10 +106,39 @@ public ColorType clone() { * The location where cache data will be stored on disk. If empty an in-memory * cache will be used for some features and a temporary disk cache for others. * HTML5 databases such as localStorage will only persist across sessions if a - * cache path is specified. + * cache path is specified. If this is set and root_cache_path is also set, the cache_path + * directory must reside within root_cache_path. */ public String cache_path = null; + /** + * The root directory for installation-specific data and the parent directory + * for profile-specific data. All CefSettings.cache_path and + * CefRequestContextSettings.cache_path values must have this parent + * directory in common. If this value is empty and CefSettings.cache_path is + * non-empty then it will default to the CefSettings.cache_path value. Any + * non-empty value must be an absolute path. If both values are empty then + * the default platform-specific directory will be used + * ("~/.config/cef_user_data" directory on Linux, "~/Library/Application + * Support/CEF/User Data" directory on MacOS, "AppData\Local\CEF\User Data" + * directory under the user profile directory on Windows). Use of the default + * directory is not recommended in production applications (see below). + * + * Multiple application instances writing to the same root_cache_path + * directory could result in data corruption. A process singleton lock based + * on the root_cache_path value is therefore used to protect against this. + * This singleton behavior applies to all CEF-based applications using + * version 120 or newer. You should customize root_cache_path for your + * application and implement CefAppHandler:: + * onAlreadyRunningAppRelaunch, which will then be called on any app relaunch + * with the same root_cache_path value. + * + * Failure to set the root_cache_path value correctly may result in startup + * crashes or other unexpected behaviors (for example, the sandbox blocking + * read/write access to certain files). + */ + public String root_cache_path = null; + /** * To persist session cookies (cookies without an expiry date or validity * interval) by default when using the global cookie manager set this value to @@ -245,6 +274,7 @@ public CefSettings clone() { tmp.windowless_rendering_enabled = windowless_rendering_enabled; tmp.command_line_args_disabled = command_line_args_disabled; tmp.cache_path = cache_path; + tmp.root_cache_path = root_cache_path; tmp.persist_session_cookies = persist_session_cookies; tmp.user_agent = user_agent; tmp.user_agent_product = user_agent_product; diff --git a/java/org/cef/SystemBootstrap.java b/java/org/cef/SystemBootstrap.java index 0a217ac4..342aaa82 100644 --- a/java/org/cef/SystemBootstrap.java +++ b/java/org/cef/SystemBootstrap.java @@ -13,7 +13,9 @@ public class SystemBootstrap { /** * Simple interface for how a library by name should be loaded. */ - static public interface Loader { public void loadLibrary(String libname); } + static public interface Loader { + public void loadLibrary(String libname); + } /** * Default implementation is to call System.loadLibrary diff --git a/java/org/cef/browser/CefBrowser.java b/java/org/cef/browser/CefBrowser.java index e73bae58..2b877f92 100644 --- a/java/org/cef/browser/CefBrowser.java +++ b/java/org/cef/browser/CefBrowser.java @@ -14,8 +14,7 @@ import org.cef.misc.CefPdfPrintSettings; import org.cef.network.CefRequest; -import java.awt.Component; -import java.awt.Point; +import java.awt.*; import java.awt.image.BufferedImage; import java.util.Vector; import java.util.concurrent.CompletableFuture; @@ -119,20 +118,20 @@ public interface CefBrowser { * @param identifier The unique frame identifier * @return The frame or NULL if not found */ - public CefFrame getFrame(long identifier); + public CefFrame getFrameByIdentifier(String identifier); /** * Returns the frame with the specified name, or NULL if not found. * @param name The specified name * @return The frame or NULL if not found */ - public CefFrame getFrame(String name); + public CefFrame getFrameByName(String name); /** * Returns the identifiers of all existing frames. * @return All identifiers of existing frames. */ - public Vector getFrameIdentifiers(); + public Vector getFrameIdentifiers(); /** * Returns the names of all existing frames. @@ -331,19 +330,29 @@ public void runFileDialog(FileDialogMode mode, String title, String defaultFileP public void stopFinding(boolean clearSelection); /** - * Get an instance of the dev tools to be displayed in its own window or to be + * Get an instance of the DevTools to be displayed in its own window or to be * embedded within your UI. Only one instance per browser is available. */ public CefBrowser getDevTools(); /** - * Get an instance of the dev tools to be displayed in its own window or to be + * Get an instance of the DevTools to be displayed in its own window or to be * embedded within your UI. Only one instance per browser is available. * * @param inspectAt a position in the UI which should be inspected. */ public CefBrowser getDevTools(Point inspectAt); + /** + * Get an instance of a client that can be used to leverage the DevTools + * protocol. Only one instance per browser is available. + * + * @see {@link CefDevToolsClient} + * @return DevTools client, or null if this browser is not yet created + * or if it is closed or closing + */ + public CefDevToolsClient getDevToolsClient(); + /** * If a misspelled word is currently selected in an editable node calling * this method will replace it with the specified |word|. @@ -374,4 +383,26 @@ public void runFileDialog(FileDialogMode mode, String title, String defaultFileP * @throws UnsupportedOperationException if not supported */ public CompletableFuture createScreenshot(boolean nativeResolution); + + /** + * Set the maximum rate in frames per second (fps) that {@code CefRenderHandler::onPaint} + * will be called for a windowless browser. The actual fps may be + * lower if the browser cannot generate frames at the requested rate. The + * minimum value is 1, and the maximum value is 60 (default 30). + * + * @param frameRate the maximum frame rate + * @throws UnsupportedOperationException if not supported + */ + public void setWindowlessFrameRate(int frameRate); + + /** + * Returns the maximum rate in frames per second (fps) that {@code CefRenderHandler::onPaint} + * will be called for a windowless browser. The actual fps may be lower if the browser cannot + * generate frames at the requested rate. The minimum value is 1, and the maximum value is 60 + * (default 30). + * + * @return the framerate, 0 if an error occurs + * @throws UnsupportedOperationException if not supported + */ + public CompletableFuture getWindowlessFrameRate(); } diff --git a/java/org/cef/browser/CefBrowserFactory.java b/java/org/cef/browser/CefBrowserFactory.java index 98a1678e..4d1826d0 100644 --- a/java/org/cef/browser/CefBrowserFactory.java +++ b/java/org/cef/browser/CefBrowserFactory.java @@ -4,6 +4,7 @@ package org.cef.browser; +import org.cef.CefBrowserSettings; import org.cef.CefClient; /** @@ -11,7 +12,7 @@ */ public class CefBrowserFactory { public static CefBrowser create(CefClient client, String url, - boolean isTransparent, CefRequestContext context) { - return new CefBrowserOsr(client, url, isTransparent, context); + boolean isTransparent, CefRequestContext context, CefBrowserSettings settings) { + return new CefBrowserOsr(client, url, isTransparent, context, settings); } } diff --git a/java/org/cef/browser/CefBrowserOsr.java b/java/org/cef/browser/CefBrowserOsr.java index cd80d9ba..d463a746 100644 --- a/java/org/cef/browser/CefBrowserOsr.java +++ b/java/org/cef/browser/CefBrowserOsr.java @@ -4,6 +4,7 @@ package org.cef.browser; +import org.cef.CefBrowserSettings; import org.cef.CefClient; import org.cef.callback.CefDragData; import org.cef.handler.CefRenderHandler; @@ -17,6 +18,7 @@ import java.awt.image.BufferedImage; import java.nio.ByteBuffer; import java.util.concurrent.CompletableFuture; +import java.util.function.Consumer; /** * This class represents an off-screen rendered browser. @@ -32,13 +34,14 @@ public class CefBrowserOsr extends CefBrowser_N implements CefRenderHandler { private int depth_per_component = 8; private boolean isTransparent_; - public CefBrowserOsr(CefClient client, String url, boolean transparent, CefRequestContext context) { - this(client, url, transparent, context, null, null); + public CefBrowserOsr(CefClient client, String url, boolean transparent, CefRequestContext context, + CefBrowserSettings settings) { + this(client, url, transparent, context, null, null, settings); } private CefBrowserOsr(CefClient client, String url, boolean transparent, - CefRequestContext context, CefBrowserOsr parent, Point inspectAt) { - super(client, url, context, parent, inspectAt); + CefRequestContext context, CefBrowserOsr parent, Point inspectAt, CefBrowserSettings settings) { + super(client, url, context, parent, inspectAt, settings); isTransparent_ = transparent; } @@ -83,6 +86,21 @@ public void onPopupSize(CefBrowser browser, Rectangle size) { public void onPaint(CefBrowser browser, boolean popup, Rectangle[] dirtyRects, ByteBuffer buffer, int width, int height) { } + @Override + public void addOnPaintListener(Consumer listener) { + + } + + @Override + public void setOnPaintListener(Consumer listener) { + + } + + @Override + public void removeOnPaintListener(Consumer listener) { + + } + @Override public boolean onCursorChange(CefBrowser browser, final int cursorType) { return true; diff --git a/java/org/cef/browser/CefBrowserWr.java b/java/org/cef/browser/CefBrowserWr.java new file mode 100644 index 00000000..e69de29b diff --git a/java/org/cef/browser/CefBrowser_N.java b/java/org/cef/browser/CefBrowser_N.java index 6c3749f9..1cdec72a 100644 --- a/java/org/cef/browser/CefBrowser_N.java +++ b/java/org/cef/browser/CefBrowser_N.java @@ -4,13 +4,10 @@ package org.cef.browser; +import org.cef.CefBrowserSettings; import org.cef.CefClient; -import org.cef.browser.CefRequestContext; -import org.cef.callback.CefDragData; -import org.cef.callback.CefNativeAdapter; -import org.cef.callback.CefPdfPrintCallback; -import org.cef.callback.CefRunFileDialogCallback; -import org.cef.callback.CefStringVisitor; +import org.cef.browser.CefDevToolsClient.DevToolsException; +import org.cef.callback.*; import org.cef.event.CefKeyEvent; import org.cef.event.CefMouseEvent; import org.cef.event.CefMouseWheelEvent; @@ -21,14 +18,9 @@ import org.cef.misc.CefPdfPrintSettings; import org.cef.network.CefRequest; -import java.awt.Component; -import java.awt.Point; -import java.awt.Rectangle; -import java.awt.Window; -import java.awt.event.WindowEvent; +import java.awt.*; import java.util.Vector; - -import javax.swing.SwingUtilities; +import java.util.concurrent.CompletableFuture; /** * This class represents all methods which are connected to the @@ -44,17 +36,23 @@ public abstract class CefBrowser_N extends CefNativeAdapter implements CefBrowse private volatile CefBrowser_N parent_ = null; private volatile Point inspectAt_ = null; private volatile CefBrowser_N devTools_ = null; + private volatile CefDevToolsClient devToolsClient_ = null; private boolean closeAllowed_ = false; private volatile boolean isClosed_ = false; private volatile boolean isClosing_ = false; + private final CefBrowserSettings settings_; protected CefBrowser_N(CefClient client, String url, CefRequestContext context, - CefBrowser_N parent, Point inspectAt) { + CefBrowser_N parent, Point inspectAt, CefBrowserSettings settings) { client_ = client; url_ = url; request_context_ = context; parent_ = parent; inspectAt_ = inspectAt; + if (settings != null) + settings_ = settings.clone(); + else + settings_ = new CefBrowserSettings(); } protected String getUrl() { @@ -117,6 +115,9 @@ public synchronized void onBeforeClose() { parent_.devTools_ = null; parent_ = null; } + if (devToolsClient_ != null) { + devToolsClient_.close(); + } } @Override @@ -132,6 +133,37 @@ public synchronized CefBrowser getDevTools(Point inspectAt) { return devTools_; } + @Override + public synchronized CefDevToolsClient getDevToolsClient() { + if (!isPending_ || isClosing_ || isClosed_) { + return null; + } + if (devToolsClient_ == null || devToolsClient_.isClosed()) { + devToolsClient_ = new CefDevToolsClient(this); + } + return devToolsClient_; + } + + CompletableFuture executeDevToolsMethod(String method, String parametersAsJson) { + CompletableFuture future = new CompletableFuture<>(); + N_ExecuteDevToolsMethod(method, parametersAsJson, new IntCallback() { + @Override + public void onComplete(int generatedMessageId) { + if (generatedMessageId <= 0) { + future.completeExceptionally(new DevToolsException( + String.format("Failed to execute DevTools method %s", method))); + } else { + future.complete(generatedMessageId); + } + } + }); + return future; + } + + CefRegistration addDevToolsMessageObserver(CefDevToolsMessageObserver observer) { + return N_AddDevToolsMessageObserver(observer); + } + protected abstract CefBrowser_N createDevToolsBrowser(CefClient client, String url, CefRequestContext context, CefBrowser_N parent, Point inspectAt); @@ -142,8 +174,8 @@ protected void createBrowser(CefClientHandler clientHandler, long windowHandle, boolean osr, boolean transparent, CefRequestContext context) { if (getNativeRef("CefBrowser") == 0 && !isPending_) { try { - N_CreateBrowser( - clientHandler, windowHandle, url, osr, transparent, context); + N_CreateBrowser(clientHandler, windowHandle, url, osr, transparent, context, + settings_); } catch (UnsatisfiedLinkError err) { err.printStackTrace(); } @@ -297,9 +329,9 @@ public CefFrame getFocusedFrame() { } @Override - public CefFrame getFrame(long identifier) { + public CefFrame getFrameByIdentifier(String identifier) { try { - return N_GetFrame(identifier); + return N_GetFrameByIdentifier(identifier); } catch (UnsatisfiedLinkError ule) { ule.printStackTrace(); return null; @@ -307,9 +339,9 @@ public CefFrame getFrame(long identifier) { } @Override - public CefFrame getFrame(String name) { + public CefFrame getFrameByName(String name) { try { - return N_GetFrame2(name); + return N_GetFrameByName(name); } catch (UnsatisfiedLinkError ule) { ule.printStackTrace(); return null; @@ -317,7 +349,7 @@ public CefFrame getFrame(String name) { } @Override - public Vector getFrameIdentifiers() { + public Vector getFrameIdentifiers() { try { return N_GetFrameIdentifiers(); } catch (UnsatisfiedLinkError ule) { @@ -366,6 +398,7 @@ public boolean hasDocument() { return false; } + @Override public void viewSource() { try { N_ViewSource(); @@ -374,6 +407,7 @@ public void viewSource() { } } + @Override public void getSource(CefStringVisitor visitor) { try { N_GetSource(visitor); @@ -382,6 +416,7 @@ public void getSource(CefStringVisitor visitor) { } } + @Override public void getText(CefStringVisitor visitor) { try { N_GetText(visitor); @@ -728,11 +763,38 @@ protected final void notifyMoveOrResizeStarted() { } } + public void setWindowlessFrameRate(int frameRate) { + try { + N_SetWindowlessFrameRate(frameRate); + } catch (UnsatisfiedLinkError ule) { + ule.printStackTrace(); + } + } + + public CompletableFuture getWindowlessFrameRate() { + final CompletableFuture future = new CompletableFuture<>(); + try { + N_GetWindowlessFrameRate(future::complete); + } catch (UnsatisfiedLinkError ule) { + ule.printStackTrace(); + future.complete(0); + } + return future; + } + + private interface IntCallback { + void onComplete(int value); + } + private final native boolean N_CreateBrowser(CefClientHandler clientHandler, long windowHandle, String url, boolean osr, boolean transparent, - CefRequestContext context); + CefRequestContext context, CefBrowserSettings settings); private final native boolean N_CreateDevTools(CefBrowser parent, CefClientHandler clientHandler, long windowHandle, boolean osr, boolean transparent, Point inspectAt); + private final native void N_ExecuteDevToolsMethod( + String method, String parametersAsJson, IntCallback callback); + private final native CefRegistration N_AddDevToolsMessageObserver( + CefDevToolsMessageObserver observer); private final native long N_GetWindowHandle(long surfaceHandle); private final native boolean N_CanGoBack(); private final native void N_GoBack(); @@ -745,9 +807,9 @@ private final native boolean N_CreateDevTools(CefBrowser parent, CefClientHandle private final native int N_GetIdentifier(); private final native CefFrame N_GetMainFrame(); private final native CefFrame N_GetFocusedFrame(); - private final native CefFrame N_GetFrame(long identifier); - private final native CefFrame N_GetFrame2(String name); - private final native Vector N_GetFrameIdentifiers(); + private final native CefFrame N_GetFrameByIdentifier(String identifier); + private final native CefFrame N_GetFrameByName(String name); + private final native Vector N_GetFrameIdentifiers(); private final native Vector N_GetFrameNames(); private final native int N_GetFrameCount(); private final native boolean N_IsPopup(); @@ -790,4 +852,6 @@ private final native void N_DragTargetDragEnter( private final native void N_DragSourceSystemDragEnded(); private final native void N_UpdateUI(Rectangle contentRect, Rectangle browserRect); private final native void N_NotifyMoveOrResizeStarted(); + private final native void N_SetWindowlessFrameRate(int frameRate); + private final native void N_GetWindowlessFrameRate(IntCallback frameRateCallback); } diff --git a/java/org/cef/browser/CefDevToolsClient.java b/java/org/cef/browser/CefDevToolsClient.java new file mode 100644 index 00000000..ee119469 --- /dev/null +++ b/java/org/cef/browser/CefDevToolsClient.java @@ -0,0 +1,165 @@ +// Copyright (c) 2024 The Chromium Embedded Framework Authors. All rights +// reserved. Use of this source code is governed by a BSD-style license that +// can be found in the LICENSE file. + +package org.cef.browser; + +import java.util.Collections; +import java.util.HashMap; +import java.util.LinkedHashSet; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.CompletableFuture; + +public class CefDevToolsClient implements AutoCloseable { + private final Map> queuedCommands_ = + Collections.synchronizedMap(new HashMap<>()); + private final Set eventListeners_ = + Collections.synchronizedSet(new LinkedHashSet<>()); + private CefRegistration registration_; + private final CefBrowser_N browser_; + + /** + * Use {@link CefBrowser#getDevToolsClient()} to get an instance of this class. + */ + CefDevToolsClient(CefBrowser_N browser) { + this.browser_ = browser; + + registration_ = browser.addDevToolsMessageObserver(new CefDevToolsMessageObserver() { + @Override + public void onDevToolsMethodResult( + CefBrowser browser, int messageId, boolean success, String result) { + CompletableFuture future = getQueuedCommand(messageId); + if (success) { + future.complete(result); + } else { + future.completeExceptionally( + new DevToolsException("DevTools method failed", result)); + } + } + + @Override + public void onDevToolsEvent(CefBrowser browser, String method, String parameters) { + for (EventListener eventListener : eventListeners_) { + eventListener.onEvent(method, parameters); + } + } + }); + } + + @Override + public void close() { + queuedCommands_.clear(); + eventListeners_.clear(); + registration_ = null; + } + + public boolean isClosed() { + return registration_ == null; + } + + private CompletableFuture getQueuedCommand(Integer messageId) { + return queuedCommands_.computeIfAbsent(messageId, key -> new CompletableFuture<>()); + } + + /** + * Execute a method call over the DevTools protocol. See the DevTools protocol documentation + * for details of supported methods and the expected syntax for parameters. + * + *

If an error occurs the returned future is completed exceptionally, otherwise its value is + * asynchronously set to the method result. + * + *

Call {@link #addEventListener(String, EventListener)} to subscribe to events. + * + * @param method the method name + * @return return a future with the method result if the method was executed successfully + */ + public CompletableFuture executeDevToolsMethod(String method) { + return executeDevToolsMethod(method, null); + } + + /** + * Execute a method call over the DevTools protocol. See the DevTools protocol documentation + * for details of supported methods and the expected syntax for parameters. + * + *

If an error occurs the returned future is completed exceptionally, otherwise its value is + * asynchronously set to the method result. + * + *

Call {@link #addEventListener(String, EventListener)} to subscribe to events. + * + * @param method the method name + * @param parametersAsJson JSON object with parameters, or null if no parameters are needed + * @return return a future with the method result if the method was executed successfully + */ + public CompletableFuture executeDevToolsMethod(String method, String parametersAsJson) { + if (isClosed()) { + CompletableFuture future = new CompletableFuture<>(); + future.completeExceptionally(new DevToolsException("Client is closed")); + return future; + } + + return browser_.executeDevToolsMethod(method, parametersAsJson) + .thenCompose(this::getQueuedCommand); + } + + /** + * Add an event listener for DevTools protocol events. Events by default are disabled + * and need to be enabled on a per domain basis, e.g. by sending Network.enable to enable + * network related events. + * + * @param eventListener the listener to add + */ + public void addEventListener(EventListener eventListener) { + eventListeners_.add(eventListener); + } + + /** + * Remove an event listener for DevTools protocol events. + * + * @param eventListener the listener to remove + */ + public void removeEventListener(EventListener eventListener) { + eventListeners_.remove(eventListener); + } + + public interface EventListener { + /** + * Method that will be called on receipt of an event. + * @param eventName the event name + * @param messageAsJson JSON object with the event message + */ + void onEvent(String eventName, String messageAsJson); + } + + public static final class DevToolsException extends Exception { + private static final long serialVersionUID = 3952948449841375372L; + + private final String json_; + + public DevToolsException(String message) { + this(message, null); + } + + public DevToolsException(String message, String json) { + super(message); + this.json_ = json; + } + + @Override + public String getMessage() { + String message = super.getMessage(); + if (json_ != null) message += ": " + json_; + return message; + } + + /** + * JSON object with the error details that were passed back by the DevTools + * host, or null if no further details are available. + */ + public String getJson() { + return json_; + } + } +} diff --git a/java/org/cef/browser/CefDevToolsMessageObserver.java b/java/org/cef/browser/CefDevToolsMessageObserver.java new file mode 100644 index 00000000..3a851356 --- /dev/null +++ b/java/org/cef/browser/CefDevToolsMessageObserver.java @@ -0,0 +1,34 @@ +// Copyright (c) 2024 The Chromium Embedded Framework Authors. All rights +// reserved. Use of this source code is governed by a BSD-style license that +// can be found in the LICENSE file. + +package org.cef.browser; + +/** + * Used internally by {@link CefDevToolsClient}. + *

+ * Callback interface for {@link CefBrowser#addDevToolsMessageObserver(CefDevToolsMessageObserver)}. + * The methods of this class will be called on the CEF UI thread. + */ +interface CefDevToolsMessageObserver { + /** + * Method that will be called after attempted execution of a DevTools protocol method. + * + * @param browser the originating browser instance + * @param messageId the ID that identifies the originating method call + * @param success if the method succeeded, |success| will be true and |result| will be a JSON + * object containing the method call result. If the method call failed, |success| will + * be false and |result| will be a JSON object describing the error. + * @param result method call result or an error + */ + void onDevToolsMethodResult(CefBrowser browser, int messageId, boolean success, String result); + + /** + * Method that will be called on receipt of a DevTools protocol event. + * + * @param browser the originating browser instance + * @param method the method name + * @param parameters the event data + */ + void onDevToolsEvent(CefBrowser browser, String method, String parameters); +} diff --git a/java/org/cef/browser/CefFrame.java b/java/org/cef/browser/CefFrame.java index 3a2393fb..a64b4ed9 100644 --- a/java/org/cef/browser/CefFrame.java +++ b/java/org/cef/browser/CefFrame.java @@ -14,11 +14,11 @@ public interface CefFrame { void dispose(); /** - * Returns the globally unique identifier for this frame or < 0 if the + * Returns the globally unique identifier for this frame or an empty string if the * underlying frame does not yet exist. * @return The frame identifier */ - long getIdentifier(); + String getIdentifier(); /** * Emits the URL currently loaded in this frame. @@ -98,4 +98,9 @@ public interface CefFrame { * Execute paste in this frame. */ public void paste(); -} \ No newline at end of file + + /** + * Execute selectAll in this frame. + */ + public void selectAll(); +} diff --git a/java/org/cef/browser/CefFrame_N.java b/java/org/cef/browser/CefFrame_N.java index 8e129f1a..0bd1c6af 100644 --- a/java/org/cef/browser/CefFrame_N.java +++ b/java/org/cef/browser/CefFrame_N.java @@ -30,12 +30,12 @@ public void dispose() { } @Override - public long getIdentifier() { + public String getIdentifier() { try { return N_GetIdentifier(getNativeRef(null)); } catch (UnsatisfiedLinkError ule) { ule.printStackTrace(); - return -1; + return null; } } @@ -148,8 +148,16 @@ public void paste() { } } + public void selectAll() { + try { + N_SelectAll(getNativeRef(null)); + } catch (UnsatisfiedLinkError ule) { + ule.printStackTrace(); + } + } + private final native void N_Dispose(long self); - private final native long N_GetIdentifier(long self); + private final native String N_GetIdentifier(long self); private final native String N_GetURL(long self); private final native String N_GetName(long self); private final native boolean N_IsMain(long self); @@ -162,4 +170,5 @@ public void paste() { private final native void N_Cut(long self); private final native void N_Copy(long self); private final native void N_Paste(long self); + private final native void N_SelectAll(long self); } diff --git a/java/org/cef/browser/CefPaintEvent.java b/java/org/cef/browser/CefPaintEvent.java new file mode 100644 index 00000000..aed9af31 --- /dev/null +++ b/java/org/cef/browser/CefPaintEvent.java @@ -0,0 +1,51 @@ +// Copyright (c) 2024 The Chromium Embedded Framework Authors. All rights +// reserved. Use of this source code is governed by a BSD-style license that +// can be found in the LICENSE file. + +package org.cef.browser; + +import java.awt.*; +import java.nio.ByteBuffer; + +public class CefPaintEvent { + private final CefBrowser browser; + private final boolean popup; + private final Rectangle[] dirtyRects; + private final ByteBuffer renderedFrame; + private final int width; + private final int height; + + public CefPaintEvent(CefBrowser browser, boolean popup, Rectangle[] dirtyRects, + ByteBuffer renderedFrame, int width, int height) { + this.browser = browser; + this.popup = popup; + this.dirtyRects = dirtyRects; + this.renderedFrame = renderedFrame; + this.width = width; + this.height = height; + } + + public CefBrowser getBrowser() { + return browser; + } + + public boolean getPopup() { + return popup; + } + + public Rectangle[] getDirtyRects() { + return dirtyRects; + } + + public ByteBuffer getRenderedFrame() { + return renderedFrame; + } + + public int getWidth() { + return width; + } + + public int getHeight() { + return height; + } +} \ No newline at end of file diff --git a/java/org/cef/browser/CefRegistration.java b/java/org/cef/browser/CefRegistration.java new file mode 100644 index 00000000..11051404 --- /dev/null +++ b/java/org/cef/browser/CefRegistration.java @@ -0,0 +1,24 @@ +// Copyright (c) 2024 The Chromium Embedded Framework Authors. All rights +// reserved. Use of this source code is governed by a BSD-style license that +// can be found in the LICENSE file. + +package org.cef.browser; + +/** + * Used internally by {@link CefDevToolsClient}. + *

+ * Handle to observer registration, As long as this object is alive, the observer will stay + * registered. + */ +abstract class CefRegistration { + /** + * Removes the native reference from an unused object. + */ + public abstract void dispose(); + + @Override + public void finalize() throws Throwable { + dispose(); + super.finalize(); + } +} diff --git a/java/org/cef/browser/CefRegistration_N.java b/java/org/cef/browser/CefRegistration_N.java new file mode 100644 index 00000000..a7defd13 --- /dev/null +++ b/java/org/cef/browser/CefRegistration_N.java @@ -0,0 +1,33 @@ +// Copyright (c) 2024 The Chromium Embedded Framework Authors. All rights +// reserved. Use of this source code is governed by a BSD-style license that +// can be found in the LICENSE file. + +package org.cef.browser; + +import org.cef.callback.CefNative; + +class CefRegistration_N extends CefRegistration implements CefNative { + // Used internally to store a pointer to the CEF object. + private long N_CefHandle = 0; + + @Override + public void setNativeRef(String identifier, long nativeRef) { + N_CefHandle = nativeRef; + } + + @Override + public long getNativeRef(String identifier) { + return N_CefHandle; + } + + @Override + public void dispose() { + try { + N_Dispose(N_CefHandle); + } catch (UnsatisfiedLinkError ule) { + ule.printStackTrace(); + } + } + + private final native void N_Dispose(long self); +} diff --git a/java/org/cef/handler/CefAppHandler.java b/java/org/cef/handler/CefAppHandler.java index 095e4747..b6ede710 100644 --- a/java/org/cef/handler/CefAppHandler.java +++ b/java/org/cef/handler/CefAppHandler.java @@ -72,4 +72,23 @@ public interface CefAppHandler { * currently pending scheduled call should be cancelled. */ public void onScheduleMessagePumpWork(long delay_ms); + + /** + * Implement this method to provide app-specific behavior when an already + * running app is relaunched with the same CefSettings.root_cache_path value. + * For example, activate an existing app window or create a new app window. + * |command_line| will be read-only. Do not keep a reference to + * |command_line| outside of this method. Return true if the relaunch is + * handled or false for default relaunch behavior. Default behavior will + * create a new default styled Chrome window. + * + * To avoid cache corruption only a single app instance is allowed to run for + * a given CefSettings.root_cache_path value. On relaunch the app checks a + * process singleton lock and then forwards the new launch arguments to the + * already running app process before exiting early. Client apps should + * therefore check the CefInitialize() return value for early exit before + * proceeding. + */ + public boolean onAlreadyRunningAppRelaunch( + CefCommandLine command_line, String current_directory); } diff --git a/java/org/cef/handler/CefAppHandlerAdapter.java b/java/org/cef/handler/CefAppHandlerAdapter.java index d74eee48..9947b74c 100644 --- a/java/org/cef/handler/CefAppHandlerAdapter.java +++ b/java/org/cef/handler/CefAppHandlerAdapter.java @@ -32,9 +32,10 @@ public void onBeforeCommandLineProcessing(String process_type, CefCommandLine co continue; } // Arguments with '--', '-' and, on Windows, '/' prefixes are considered switches. - int switchCnt = arg.startsWith("--") - ? 2 - : arg.startsWith("/") ? 1 : arg.startsWith("-") ? 1 : 0; + int switchCnt = arg.startsWith("--") ? 2 + : arg.startsWith("/") ? 1 + : arg.startsWith("-") ? 1 + : 0; switch (switchCnt) { case 2: // An argument of "--" will terminate switch parsing with all subsequent @@ -47,11 +48,13 @@ public void onBeforeCommandLineProcessing(String process_type, CefCommandLine co case 1: { // Switches can optionally have a value specified using the '=' delimiter // (e.g. "-switch=value"). - String[] switchVals = arg.substring(switchCnt).split("="); - if (switchVals.length == 2) { - command_line.appendSwitchWithValue(switchVals[0], switchVals[1]); + String switchStr = arg.substring(switchCnt); + int index = switchStr.indexOf('='); + if (index > 0) { + command_line.appendSwitchWithValue( + switchStr.substring(0, index), switchStr.substring(index + 1)); } else { - command_line.appendSwitch(switchVals[0]); + command_line.appendSwitch(switchStr); } break; } @@ -88,4 +91,11 @@ public void onContextInitialized() { public void onScheduleMessagePumpWork(long delay_ms) { CefApp.getInstance().doMessageLoopWork(delay_ms); } + + @Override + public boolean onAlreadyRunningAppRelaunch( + CefCommandLine command_line, String current_directory) { + // The default implementation does nothing + return false; + } } diff --git a/java/org/cef/handler/CefDialogHandler.java b/java/org/cef/handler/CefDialogHandler.java index 311de4cb..12ffdea7 100644 --- a/java/org/cef/handler/CefDialogHandler.java +++ b/java/org/cef/handler/CefDialogHandler.java @@ -38,11 +38,17 @@ enum FileDialogMode { * "image/*"), (b) individual file extensions (e.g. ".txt" or ".png"), or (c) * combined description and file extension delimited using "|" and ";" (e.g. * "Image Types|.png;.gif;.jpg"). + * @param acceptExtensions provides the semicolon-delimited expansion of MIME + * types to file extensions (if known, or empty string otherwise). + * @param acceptDescriptions provides the descriptions for MIME types (if known, + * or empty string otherwise). For example, the "image/*" mime type might + * have extensions ".png;.jpg;.bmp;..." and description "Image Files". * @param callback is a callback handler for handling own file dialogs. * * @return To display a custom dialog return true and execute callback. * To display the default dialog return false. */ public boolean onFileDialog(CefBrowser browser, FileDialogMode mode, String title, - String defaultFilePath, Vector acceptFilters, CefFileDialogCallback callback); + String defaultFilePath, Vector acceptFilters, Vector acceptExtensions, + Vector acceptDescriptions, CefFileDialogCallback callback); } diff --git a/java/org/cef/handler/CefDisplayHandler.java b/java/org/cef/handler/CefDisplayHandler.java index 0affefc5..f2a828eb 100644 --- a/java/org/cef/handler/CefDisplayHandler.java +++ b/java/org/cef/handler/CefDisplayHandler.java @@ -28,6 +28,13 @@ public interface CefDisplayHandler { */ public void onTitleChange(CefBrowser browser, String title); + /** + * Browser fullscreen mode changed. + * @param browser The browser generating the event. + * @param fullscreen True if fullscreen mode is on. + */ + public void onFullscreenModeChange(CefBrowser browser, boolean fullscreen); + /** * About to display a tooltip. * @param browser The browser generating the event. diff --git a/java/org/cef/handler/CefDisplayHandlerAdapter.java b/java/org/cef/handler/CefDisplayHandlerAdapter.java index 80ab96b6..90d22d50 100644 --- a/java/org/cef/handler/CefDisplayHandlerAdapter.java +++ b/java/org/cef/handler/CefDisplayHandlerAdapter.java @@ -24,6 +24,11 @@ public void onTitleChange(CefBrowser browser, String title) { return; } + @Override + public void onFullscreenModeChange(CefBrowser browser, boolean fullscreen) { + return; + } + @Override public boolean onTooltip(CefBrowser browser, String text) { return false; diff --git a/java/org/cef/handler/CefDownloadHandler.java b/java/org/cef/handler/CefDownloadHandler.java index 66ea49a4..3f0ee6f2 100644 --- a/java/org/cef/handler/CefDownloadHandler.java +++ b/java/org/cef/handler/CefDownloadHandler.java @@ -15,9 +15,11 @@ */ public interface CefDownloadHandler { /** - * Called before a download begins. By default the download will be canceled. - * Execute callback either asynchronously or in this method to continue the download - * if desired. + * Called before a download begins. Return true and execute |callback| either + * asynchronously or in this method to continue or cancel the download. + * Return false to proceed with default handling (cancel with Alloy style, + * download shelf with Chrome style). Do not keep a reference to + * downloadItem outside of this method. * * @param browser The desired browser. * @param downloadItem The item to be downloaded. Do not keep a reference to it outside this @@ -25,7 +27,7 @@ public interface CefDownloadHandler { * @param suggestedName is the suggested name for the download file. * @param callback start the download by calling the Continue method */ - public void onBeforeDownload(CefBrowser browser, CefDownloadItem downloadItem, + public boolean onBeforeDownload(CefBrowser browser, CefDownloadItem downloadItem, String suggestedName, CefBeforeDownloadCallback callback); /** diff --git a/java/org/cef/handler/CefDownloadHandlerAdapter.java b/java/org/cef/handler/CefDownloadHandlerAdapter.java index 8b1f46aa..f0311637 100644 --- a/java/org/cef/handler/CefDownloadHandlerAdapter.java +++ b/java/org/cef/handler/CefDownloadHandlerAdapter.java @@ -16,8 +16,10 @@ */ public abstract class CefDownloadHandlerAdapter implements CefDownloadHandler { @Override - public void onBeforeDownload(CefBrowser browser, CefDownloadItem downloadItem, - String suggestedName, CefBeforeDownloadCallback callback) {} + public boolean onBeforeDownload(CefBrowser browser, CefDownloadItem downloadItem, + String suggestedName, CefBeforeDownloadCallback callback) { + return false; + } @Override public void onDownloadUpdated( diff --git a/java/org/cef/handler/CefLoadHandler.java b/java/org/cef/handler/CefLoadHandler.java index 37d5a3e8..4f0bb831 100644 --- a/java/org/cef/handler/CefLoadHandler.java +++ b/java/org/cef/handler/CefLoadHandler.java @@ -187,12 +187,8 @@ enum ErrorCode { ERR_INVALID_HTTP_RESPONSE(-370), ERR_CONTENT_DECODING_INIT_FAILED(-371), ERR_HTTP2_RST_STREAM_NO_ERROR_RECEIVED(-372), - ERR_HTTP2_PUSHED_STREAM_NOT_AVAILABLE(-373), - ERR_HTTP2_CLAIMED_PUSHED_STREAM_RESET_BY_SERVER(-374), ERR_TOO_MANY_RETRIES(-375), ERR_HTTP2_STREAM_CLOSED(-376), - ERR_HTTP2_CLIENT_REFUSED_STREAM(-377), - ERR_HTTP2_PUSHED_RESPONSE_DOES_NOT_MATCH(-378), ERR_HTTP_RESPONSE_CODE_FAILURE(-379), ERR_QUIC_CERT_ROOT_NOT_KNOWN(-380), ERR_QUIC_GOAWAY_REQUEST_CAN_BE_RETRIED(-381), @@ -217,13 +213,6 @@ enum ErrorCode { ERR_INVALID_WEB_BUNDLE(-505), ERR_TRUST_TOKEN_OPERATION_FAILED(-506), ERR_TRUST_TOKEN_OPERATION_SUCCESS_WITHOUT_SENDING_REQUEST(-507), - ERR_FTP_FAILED(-601), - ERR_FTP_SERVICE_UNAVAILABLE(-602), - ERR_FTP_TRANSFER_ABORTED(-603), - ERR_FTP_FILE_BUSY(-604), - ERR_FTP_SYNTAX_ERROR(-605), - ERR_FTP_COMMAND_NOT_SUPPORTED(-606), - ERR_FTP_BAD_COMMAND_SEQUENCE(-607), ERR_PKCS12_IMPORT_BAD_PASSWORD(-701), ERR_PKCS12_IMPORT_FAILED(-702), ERR_IMPORT_CA_CERT_NOT_CA(-703), diff --git a/java/org/cef/handler/CefRenderHandler.java b/java/org/cef/handler/CefRenderHandler.java index 0a94bb2f..258df884 100644 --- a/java/org/cef/handler/CefRenderHandler.java +++ b/java/org/cef/handler/CefRenderHandler.java @@ -5,11 +5,13 @@ package org.cef.handler; import org.cef.browser.CefBrowser; +import org.cef.browser.CefPaintEvent; import org.cef.callback.CefDragData; import java.awt.Point; import java.awt.Rectangle; import java.nio.ByteBuffer; +import java.util.function.Consumer; /** * Implement this interface to handle events when window rendering is disabled. @@ -65,6 +67,24 @@ public interface CefRenderHandler { public void onPaint(CefBrowser browser, boolean popup, Rectangle[] dirtyRects, ByteBuffer buffer, int width, int height); + /** + * Add provided listener. + * @param listener Code that gets executed after a frame was rendered. + */ + public void addOnPaintListener(Consumer listener); + + /** + * Remove existing listeners and replace with provided listener. + * @param listener Code that gets executed after a frame was rendered. + */ + public void setOnPaintListener(Consumer listener); + + /** + * Remove provided listener. + * @param listener Code that gets executed after a frame was rendered. + */ + public void removeOnPaintListener(Consumer listener); + /** * Handle cursor changes. * @param browser The browser generating the event. diff --git a/java/org/cef/handler/CefRequestHandler.java b/java/org/cef/handler/CefRequestHandler.java index 7a508323..93cbe95b 100644 --- a/java/org/cef/handler/CefRequestHandler.java +++ b/java/org/cef/handler/CefRequestHandler.java @@ -24,7 +24,9 @@ enum TerminationStatus { TS_ABNORMAL_TERMINATION, //!< Non-zero exit status. TS_PROCESS_WAS_KILLED, //!< SIGKILL or task manager kill. TS_PROCESS_CRASHED, //!< Segmentation fault. - TS_PROCESS_OOM //!< Out of memory. + TS_PROCESS_OOM, //!< Out of memory. + TS_LAUNCH_FAILED, //!< Failed to launch. + TS_INTEGRITY_FAILURE //!< Integrity check failed. } /** @@ -123,6 +125,9 @@ boolean onCertificateError(CefBrowser browser, CefLoadHandler.ErrorCode cert_err * Called on the browser process UI thread when the render process terminates unexpectedly. * @param browser The corresponding browser. * @param status Indicates how the process was terminated. + * @param error_code The process error code. + * @param error_string A string description of the error. */ - void onRenderProcessTerminated(CefBrowser browser, TerminationStatus status); + void onRenderProcessTerminated( + CefBrowser browser, TerminationStatus status, int error_code, String error_string); } diff --git a/java/org/cef/handler/CefRequestHandlerAdapter.java b/java/org/cef/handler/CefRequestHandlerAdapter.java index dd785529..a6c04ef6 100644 --- a/java/org/cef/handler/CefRequestHandlerAdapter.java +++ b/java/org/cef/handler/CefRequestHandlerAdapter.java @@ -51,5 +51,6 @@ public boolean onCertificateError( } @Override - public void onRenderProcessTerminated(CefBrowser browser, TerminationStatus status) {} + public void onRenderProcessTerminated( + CefBrowser browser, TerminationStatus status, int error_code, String error_string) {} } diff --git a/java/org/cef/misc/CefPdfPrintSettings.java b/java/org/cef/misc/CefPdfPrintSettings.java index 49afdc28..a014d81c 100644 --- a/java/org/cef/misc/CefPdfPrintSettings.java +++ b/java/org/cef/misc/CefPdfPrintSettings.java @@ -105,6 +105,16 @@ public enum MarginType { */ public String footer_template; + /** + * Whether or not to generate tagged (accessible) PDF. + */ + public boolean generate_tagged_pdf; + + /** + * Whether or not to embed the document outline into the PDF. + */ + public boolean generate_document_outline; + public CefPdfPrintSettings() {} @Override @@ -125,6 +135,8 @@ public CefPdfPrintSettings clone() { tmp.display_header_footer = this.display_header_footer; tmp.header_template = this.header_template; tmp.footer_template = this.footer_template; + tmp.generate_tagged_pdf = this.generate_tagged_pdf; + tmp.generate_document_outline = this.generate_document_outline; return tmp; } } diff --git a/java/tests/detailed/MainFrame.java b/java/tests/detailed/MainFrame.java index 5b1efeb5..7377a2d1 100644 --- a/java/tests/detailed/MainFrame.java +++ b/java/tests/detailed/MainFrame.java @@ -6,6 +6,7 @@ import org.cef.CefApp; import org.cef.CefApp.CefVersion; +import org.cef.CefBrowserSettings; import org.cef.CefClient; import org.cef.CefSettings; import org.cef.CefSettings.ColorType; @@ -21,6 +22,8 @@ import org.cef.network.CefCookieManager; import java.awt.BorderLayout; +import java.awt.Component; +import java.awt.GraphicsConfiguration; import java.awt.KeyboardFocusManager; import java.awt.event.FocusAdapter; import java.awt.event.FocusEvent; @@ -29,6 +32,7 @@ import javax.swing.JFrame; import javax.swing.JPanel; +import javax.swing.SwingUtilities; import tests.detailed.dialog.DownloadDialog; import tests.detailed.handler.AppHandler; @@ -58,6 +62,7 @@ public static void main(String[] args) { boolean osrEnabledArg = false; boolean transparentPaintingEnabledArg = false; boolean createImmediately = false; + int windowless_frame_rate = 0; for (String arg : args) { arg = arg.toLowerCase(); if (arg.equals("--off-screen-rendering-enabled")) { @@ -66,6 +71,8 @@ public static void main(String[] args) { transparentPaintingEnabledArg = true; } else if (arg.equals("--create-immediately")) { createImmediately = true; + } else if (arg.equals("--windowless-frame-rate-60")) { + windowless_frame_rate = 60; } } @@ -73,10 +80,21 @@ public static void main(String[] args) { // MainFrame keeps all the knowledge to display the embedded browser // frame. - final MainFrame frame = new MainFrame( - osrEnabledArg, transparentPaintingEnabledArg, createImmediately, args); + final MainFrame frame = new MainFrame(osrEnabledArg, transparentPaintingEnabledArg, + createImmediately, windowless_frame_rate, args); frame.setSize(800, 600); frame.setVisible(true); + + if (osrEnabledArg && windowless_frame_rate != 0) { + frame.getBrowser().getWindowlessFrameRate().thenAccept( + framerate -> System.out.println("Framerate is:" + framerate)); + + frame.getBrowser().setWindowlessFrameRate(2); + frame.getBrowser().getWindowlessFrameRate().thenAccept( + framerate -> System.out.println("Framerate is:" + framerate)); + + frame.getBrowser().setWindowlessFrameRate(windowless_frame_rate); + } } private final CefClient client_; @@ -86,9 +104,11 @@ public static void main(String[] args) { private boolean browserFocus_ = true; private boolean osr_enabled_; private boolean transparent_painting_enabled_; + private JPanel contentPanel_; + private JFrame fullscreenFrame_; public MainFrame(boolean osrEnabled, boolean transparentPaintingEnabled, - boolean createImmediately, String[] args) { + boolean createImmediately, int windowless_frame_rate, String[] args) { this.osr_enabled_ = osrEnabled; this.transparent_painting_enabled_ = transparentPaintingEnabled; @@ -163,6 +183,10 @@ public void onTitleChange(CefBrowser browser, String title) { public void onStatusMessage(CefBrowser browser, String value) { status_panel_.setStatusText(value); } + @Override + public void onFullscreenModeChange(CefBrowser browser, boolean fullscreen) { + setBrowserFullscreen(fullscreen); + } }); // 2.2) To disable/enable navigation buttons and to display a prgress bar @@ -175,19 +199,25 @@ public void onStatusMessage(CefBrowser browser, String value) { @Override public void onLoadingStateChange(CefBrowser browser, boolean isLoading, boolean canGoBack, boolean canGoForward) { - control_pane_.update(browser, isLoading, canGoBack, canGoForward); - status_panel_.setIsInProgress(isLoading); - - if (!isLoading && !errorMsg_.isEmpty()) { - browser.loadURL(DataUri.create("text/html", errorMsg_)); - errorMsg_ = ""; - } + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + control_pane_.update(browser, isLoading, canGoBack, canGoForward); + status_panel_.setIsInProgress(isLoading); + + if (!isLoading && !errorMsg_.isEmpty()) { + browser.loadURL(DataUri.create("text/html", errorMsg_)); + errorMsg_ = ""; + } + } + }); } @Override public void onLoadError(CefBrowser browser, CefFrame frame, ErrorCode errorCode, String errorText, String failedUrl) { - if (errorCode != ErrorCode.ERR_NONE && errorCode != ErrorCode.ERR_ABORTED) { + if (errorCode != ErrorCode.ERR_NONE && errorCode != ErrorCode.ERR_ABORTED + && frame == browser.getMainFrame()) { errorMsg_ = ""; errorMsg_ += "Error while loading"; errorMsg_ += ""; @@ -200,14 +230,17 @@ public void onLoadError(CefBrowser browser, CefFrame frame, ErrorCode errorCode, } }); + CefBrowserSettings browserSettings = new CefBrowserSettings(); + browserSettings.windowless_frame_rate = windowless_frame_rate; + // Create the browser. - CefBrowser browser = client_.createBrowser( - "http://www.google.com", osrEnabled, null); + CefBrowser browser = client_.createBrowser("http://www.google.com", osrEnabled, + transparentPaintingEnabled, null, browserSettings); setBrowser(browser); // Set up the UI for this example implementation. - JPanel contentPanel = createContentPanel(); - getContentPane().add(contentPanel, BorderLayout.CENTER); + contentPanel_ = createContentPanel(); + getContentPane().add(contentPanel_, BorderLayout.CENTER); // Clear focus from the browser when the address field gains focus. control_pane_.getAddressField().addFocusListener(new FocusAdapter() { @@ -239,6 +272,7 @@ public void onTakeFocus(CefBrowser browser, boolean next) { if (createImmediately) browser.createImmediately(); // Add the browser to the UI. + contentPanel_.add(getBrowser().getUIComponent(), BorderLayout.CENTER); MenuBar menuBar = new MenuBar( this, browser, control_pane_, downloadDialog, CefCookieManager.getGlobalManager()); @@ -258,6 +292,8 @@ public void onTakeFocus(CefBrowser browser, boolean next) { menuBar.addBookmark("Spellcheck Test", "client://tests/spellcheck.html"); menuBar.addBookmark("LocalStorage Test", "client://tests/localstorage.html"); menuBar.addBookmark("Transparency Test", "client://tests/transparency.html"); + menuBar.addBookmark("Fullscreen Test", + "https://www.w3schools.com/howto/tryit.asp?filename=tryhow_js_fullscreen2"); menuBar.addBookmarkSeparator(); menuBar.addBookmark( "javachromiumembedded", "https://bitbucket.org/chromiumembedded/java-cef"); @@ -281,4 +317,33 @@ public boolean isOsrEnabled() { public boolean isTransparentPaintingEnabled() { return transparent_painting_enabled_; } + + public void setBrowserFullscreen(boolean fullscreen) { + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + Component browserUI = getBrowser().getUIComponent(); + if (fullscreen) { + if (fullscreenFrame_ == null) { + fullscreenFrame_ = new JFrame(); + fullscreenFrame_.setUndecorated(true); + fullscreenFrame_.setResizable(true); + } + GraphicsConfiguration gc = MainFrame.this.getGraphicsConfiguration(); + fullscreenFrame_.setBounds(gc.getBounds()); + gc.getDevice().setFullScreenWindow(fullscreenFrame_); + + contentPanel_.remove(browserUI); + fullscreenFrame_.add(browserUI); + fullscreenFrame_.setVisible(true); + fullscreenFrame_.validate(); + } else { + fullscreenFrame_.remove(browserUI); + fullscreenFrame_.setVisible(false); + contentPanel_.add(browserUI, BorderLayout.CENTER); + contentPanel_.validate(); + } + } + }); + } } diff --git a/java/tests/detailed/dialog/DownloadDialog.java b/java/tests/detailed/dialog/DownloadDialog.java index f9717a50..c3ffaeac 100644 --- a/java/tests/detailed/dialog/DownloadDialog.java +++ b/java/tests/detailed/dialog/DownloadDialog.java @@ -143,13 +143,15 @@ void update(CefDownloadItem downloadItem, CefDownloadItemCallback callback) { } @Override - public void onBeforeDownload(CefBrowser browser, CefDownloadItem downloadItem, + public boolean onBeforeDownload(CefBrowser browser, CefDownloadItem downloadItem, String suggestedName, CefBeforeDownloadCallback callback) { callback.Continue(suggestedName, true); DownloadObject dlObject = new DownloadObject(downloadItem, suggestedName); downloadObjects_.put(downloadItem.getId(), dlObject); downloadPanel_.add(dlObject); + + return true; } @Override diff --git a/java/tests/detailed/handler/KeyboardHandler.java b/java/tests/detailed/handler/KeyboardHandler.java index 350d0f3b..6785b550 100644 --- a/java/tests/detailed/handler/KeyboardHandler.java +++ b/java/tests/detailed/handler/KeyboardHandler.java @@ -20,6 +20,32 @@ public boolean onKeyEvent(CefBrowser browser, CefKeyEvent event) { browser.executeJavaScript("alert('You pressed the space bar!');", "", 0); } return true; + } else if (event.type == CefKeyEvent.EventType.KEYEVENT_RAWKEYDOWN && event.is_system_key) { + // CMD+[key] is not working on a Mac. + // This switch statement delegates the common keyboard shortcuts to the browser + switch (event.unmodified_character) { + case 'a': + browser.getFocusedFrame().selectAll(); + break; + case 'c': + browser.getFocusedFrame().copy(); + break; + case 'v': + browser.getFocusedFrame().paste(); + break; + case 'x': + browser.getFocusedFrame().cut(); + break; + case 'z': + browser.getFocusedFrame().undo(); + break; + case 'Z': + browser.getFocusedFrame().redo(); + break; + default: + return false; + } + return true; } return false; } diff --git a/java/tests/detailed/handler/RequestHandler.java b/java/tests/detailed/handler/RequestHandler.java index d80e1251..44d102a5 100644 --- a/java/tests/detailed/handler/RequestHandler.java +++ b/java/tests/detailed/handler/RequestHandler.java @@ -161,7 +161,9 @@ public boolean onCertificateError( } @Override - public void onRenderProcessTerminated(CefBrowser browser, TerminationStatus status) { - System.out.println("render process terminated: " + status); + public void onRenderProcessTerminated( + CefBrowser browser, TerminationStatus status, int error_code, String error_string) { + System.out.println("render process terminated: " + status + " errorCode: " + error_code + + " errorString: " + error_string); } } diff --git a/java/tests/detailed/ui/MenuBar.java b/java/tests/detailed/ui/MenuBar.java index a6fe40bc..2734d525 100644 --- a/java/tests/detailed/ui/MenuBar.java +++ b/java/tests/detailed/ui/MenuBar.java @@ -4,10 +4,9 @@ package tests.detailed.ui; -import org.cef.CefApp; -import org.cef.CefClient; import org.cef.OS; import org.cef.browser.CefBrowser; +import org.cef.browser.CefDevToolsClient; import org.cef.callback.CefPdfPrintCallback; import org.cef.callback.CefRunFileDialogCallback; import org.cef.callback.CefStringVisitor; @@ -21,12 +20,10 @@ import java.awt.Container; import java.awt.Dimension; import java.awt.FlowLayout; -import java.awt.Frame; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.ComponentAdapter; import java.awt.event.ComponentEvent; -import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.awt.image.BufferedImage; import java.io.File; @@ -40,10 +37,10 @@ import javax.swing.ImageIcon; import javax.swing.JButton; +import javax.swing.JCheckBoxMenuItem; import javax.swing.JFileChooser; import javax.swing.JFrame; import javax.swing.JLabel; -import javax.swing.JLayeredPane; import javax.swing.JMenu; import javax.swing.JMenuBar; import javax.swing.JMenuItem; @@ -86,6 +83,7 @@ public void visit(String string) { private final DownloadDialog downloadDialog_; private final CefCookieManager cookieManager_; private boolean reparentPending_ = false; + private CefDevToolsClient devToolsClient_; public MenuBar(MainFrame owner, CefBrowser browser, ControlPanel control_pane, DownloadDialog downloadDialog, CefCookieManager cookieManager) { @@ -382,6 +380,37 @@ public void componentHidden(ComponentEvent e) { }); testMenu.add(showDevTools); + JMenu devToolsProtocolMenu = new JMenu("DevTools Protocol"); + JMenuItem autoDarkMode = devToolsProtocolMenu.add(new JCheckBoxMenuItem("Auto Dark Mode")); + autoDarkMode.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + // Toggle the auto dark mode override + String params = String.format("{ \"enabled\": %s }", autoDarkMode.isSelected()); + executeDevToolsMethod("Emulation.setAutoDarkModeOverride", params); + } + }); + JMenuItem checkContrast = devToolsProtocolMenu.add(new JMenuItem("Check Contrast")); + checkContrast.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + // Check contrast, which usually triggers a series of Audits.issueAdded events + executeDevToolsMethod("Audits.checkContrast"); + } + }); + JMenuItem enableCSS = devToolsProtocolMenu.add(new JMenuItem("Enable CSS Agent")); + enableCSS.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + // Enable the CSS agent, which usually triggers a series of CSS.styleSheetAdded + // events. We can only enable the CSS agent if the DOM agent is enabled first, so we + // need to chain the two commands. + executeDevToolsMethod("DOM.enable") + .thenCompose(unused -> executeDevToolsMethod("CSS.enable")); + } + }); + testMenu.add(devToolsProtocolMenu); + JMenuItem testURLRequest = new JMenuItem("URL Request"); testURLRequest.addActionListener(new ActionListener() { @Override @@ -439,7 +468,7 @@ public void run() { newwindow.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { - final MainFrame frame = new MainFrame(OS.isLinux(), false, false, null); + final MainFrame frame = new MainFrame(OS.isLinux(), false, false, 0, null); frame.setSize(800, 600); frame.setVisible(true); } @@ -547,6 +576,26 @@ private void displayScreenshot(BufferedImage aScreenshot) { frame.pack(); } + private CompletableFuture executeDevToolsMethod(String methodName) { + return executeDevToolsMethod(methodName, null); + } + + private CompletableFuture executeDevToolsMethod( + String methodName, String paramsAsJson) { + if (devToolsClient_ == null) { + devToolsClient_ = browser_.getDevToolsClient(); + devToolsClient_.addEventListener( + (method, json) -> System.out.println("CDP event " + method + ": " + json)); + } + + return devToolsClient_.executeDevToolsMethod(methodName, paramsAsJson) + .handle((error, json) -> { + System.out.println( + "CDP result of " + methodName + ": " + (error != null ? error : json)); + return null; + }); + } + public void addBookmarkSeparator() { bookmarkMenu_.addSeparator(); } diff --git a/java/tests/junittests/TestFrame.java b/java/tests/junittests/TestFrame.java index bdbc26a9..c04520ef 100644 --- a/java/tests/junittests/TestFrame.java +++ b/java/tests/junittests/TestFrame.java @@ -242,7 +242,8 @@ public boolean onCertificateError(CefBrowser browser, CefLoadHandler.ErrorCode c } @Override - public void onRenderProcessTerminated(CefBrowser browser, TerminationStatus status) {} + public void onRenderProcessTerminated( + CefBrowser browser, TerminationStatus status, int error_code, String error_string) {} // CefResourceRequestHandler methods: diff --git a/java/tests/simple/MainFrame.java b/java/tests/simple/MainFrame.java index 822c4c8f..44035d0d 100644 --- a/java/tests/simple/MainFrame.java +++ b/java/tests/simple/MainFrame.java @@ -17,6 +17,7 @@ import java.awt.BorderLayout; import java.awt.Component; +import java.awt.GraphicsConfiguration; import java.awt.KeyboardFocusManager; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; @@ -26,7 +27,9 @@ import java.awt.event.WindowEvent; import javax.swing.JFrame; +import javax.swing.JPanel; import javax.swing.JTextField; +import javax.swing.SwingUtilities; /** * This is a simple example application using JCEF. @@ -46,7 +49,9 @@ public class MainFrame extends JFrame { private final CefApp cefApp_; private final CefClient client_; private final CefBrowser browser_; + private final Component browserUI_; private boolean browserFocus_ = true; + private JFrame fullscreenFrame_; /** * To display a simple browser window, it suffices completely to create an @@ -103,7 +108,8 @@ public void stateHasChanged(org.cef.CefApp.CefAppState state) { // by calling the method "getUIComponent()" on the instance of CefBrowser. // The UI component is inherited from a java.awt.Component and therefore // it can be embedded into any AWT UI. - browser_ = client_.createBrowser(startURL, isTransparent); + browser_ = client_.createBrowser(startURL, useOSR, isTransparent); + browserUI_ = browser_.getUIComponent(); // (4) For this minimal browser, we need only a text field to enter an URL // we want to navigate to and a CefBrowser window to display the content @@ -126,6 +132,10 @@ public void actionPerformed(ActionEvent e) { public void onAddressChange(CefBrowser browser, CefFrame frame, String url) { address_.setText(url); } + @Override + public void onFullscreenModeChange(CefBrowser browser, boolean fullscreen) { + setBrowserFullscreen(fullscreen); + } }); // Clear focus from the browser when the address field gains focus. @@ -158,6 +168,7 @@ public void onTakeFocus(CefBrowser browser, boolean next) { // (5) All UI components are assigned to the default content pane of this // JFrame and afterwards the frame is made visible to the user. getContentPane().add(address_, BorderLayout.NORTH); + getContentPane().add(browserUI_, BorderLayout.CENTER); pack(); setSize(800, 600); setVisible(true); @@ -174,6 +185,34 @@ public void windowClosing(WindowEvent e) { }); } + public void setBrowserFullscreen(boolean fullscreen) { + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + if (fullscreen) { + if (fullscreenFrame_ == null) { + fullscreenFrame_ = new JFrame(); + fullscreenFrame_.setUndecorated(true); + fullscreenFrame_.setResizable(true); + } + GraphicsConfiguration gc = MainFrame.this.getGraphicsConfiguration(); + fullscreenFrame_.setBounds(gc.getBounds()); + gc.getDevice().setFullScreenWindow(fullscreenFrame_); + + getContentPane().remove(browserUI_); + fullscreenFrame_.add(browserUI_); + fullscreenFrame_.setVisible(true); + fullscreenFrame_.validate(); + } else { + fullscreenFrame_.remove(browserUI_); + fullscreenFrame_.setVisible(false); + getContentPane().add(browserUI_, BorderLayout.CENTER); + getContentPane().validate(); + } + } + }); + } + public static void main(String[] args) { // Perform startup initialization on platforms that require it. if (!CefApp.startup(args)) { diff --git a/native/CMakeLists.txt b/native/CMakeLists.txt index 0368b692..70e88f40 100644 --- a/native/CMakeLists.txt +++ b/native/CMakeLists.txt @@ -54,6 +54,8 @@ set(JCEF_SRCS CefPrintSettings_N.h CefQueryCallback_N.cpp CefQueryCallback_N.h + CefRegistration_N.cpp + CefRegistration_N.h CefRequest_N.cpp CefRequest_N.h CefCallback_N.cpp @@ -83,6 +85,8 @@ set(JCEF_SRCS cookie_visitor.cpp cookie_visitor.h critical_wait.h + devtools_message_observer.cpp + devtools_message_observer.h dialog_handler.cpp dialog_handler.h display_handler.cpp @@ -95,6 +99,8 @@ set(JCEF_SRCS drag_handler.h focus_handler.cpp focus_handler.h + int_callback.cpp + int_callback.h jcef_version.h jni_scoped_helpers.h jni_scoped_helpers.cpp diff --git a/native/CefBrowser_N.cpp b/native/CefBrowser_N.cpp index f7f17cd8..e4745e78 100644 --- a/native/CefBrowser_N.cpp +++ b/native/CefBrowser_N.cpp @@ -6,12 +6,15 @@ #include "include/base/cef_callback.h" #include "include/cef_browser.h" +#include "include/cef_parser.h" #include "include/cef_task.h" #include "include/wrapper/cef_closure_task.h" #include "browser_process_handler.h" #include "client_handler.h" #include "critical_wait.h" +#include "devtools_message_observer.h" +#include "int_callback.h" #include "jni_util.h" #include "life_span_handler.h" #include "pdf_print_callback.h" @@ -895,6 +898,7 @@ struct JNIObjectsForCreate { ScopedJNIObjectGlobal url; ScopedJNIObjectGlobal jcontext; ScopedJNIObjectGlobal jinspectAt; + ScopedJNIObjectGlobal jbrowserSettings; JNIObjectsForCreate(JNIEnv* env, jobject _jbrowser, @@ -902,7 +906,8 @@ struct JNIObjectsForCreate { jobject _jclientHandler, jstring _url, jobject _jcontext, - jobject _jinspectAt) + jobject _jinspectAt, + jobject _browserSettings) : jbrowser(env, _jbrowser), @@ -910,7 +915,8 @@ struct JNIObjectsForCreate { jclientHandler(env, _jclientHandler), url(env, _url), jcontext(env, _jcontext), - jinspectAt(env, _jinspectAt) {} + jinspectAt(env, _jinspectAt), + jbrowserSettings(env, _browserSettings) {} }; void create(std::shared_ptr objs, @@ -938,6 +944,13 @@ void create(std::shared_ptr objs, settings.background_color = CefColorSetARGB(255, 255, 255, 255); } + ScopedJNIClass cefBrowserSettings(env, "org/cef/CefBrowserSettings"); + if (cefBrowserSettings != nullptr && + objs->jbrowserSettings != nullptr) { // Dev-tools settings are null + GetJNIFieldInt(env, cefBrowserSettings, objs->jbrowserSettings, + "windowless_frame_rate", &settings.windowless_frame_rate); + } + CefRefPtr browserObj; CefString strUrl = GetJNIString(env, static_cast(objs->url.get())); @@ -994,6 +1007,26 @@ void getZoomLevel(CefRefPtr host, } } +void executeDevToolsMethod(CefRefPtr host, + const CefString& method, + const CefString& parametersAsJson, + CefRefPtr callback) { + CefRefPtr parameters = nullptr; + if (!parametersAsJson.empty()) { + CefRefPtr value = CefParseJSON( + parametersAsJson, cef_json_parser_options_t::JSON_PARSER_RFC); + + if (!value || value->GetType() != VTYPE_DICTIONARY) { + callback->onComplete(0); + return; + } + + parameters = value->GetDictionary(); + } + + callback->onComplete(host->ExecuteDevToolsMethod(0, method, parameters)); +} + // Removed because we don't care about when the native parent window changes. // This fixes a compile issue on macOS - ds58 //void OnAfterParentChanged(CefRefPtr browser) { @@ -1014,21 +1047,6 @@ void getZoomLevel(CefRefPtr host, // } //} -jobject NewJNILongVector(JNIEnv* env, const std::vector& vals) { - ScopedJNIObjectLocal jvector(env, "java/util/Vector"); - if (!jvector) - return nullptr; - - std::vector::const_iterator iter; - for (iter = vals.begin(); iter != vals.end(); ++iter) { - ScopedJNIObjectLocal argument( - env, NewJNIObject(env, "java/lang/Long", "(J)V", (jlong)*iter)); - JNI_CALL_VOID_METHOD(env, jvector, "addElement", "(Ljava/lang/Object;)V", - argument.get()); - } - return jvector.Release(); -} - CefPdfPrintSettings GetJNIPdfPrintSettings(JNIEnv* env, jobject obj) { CefString tmp; CefPdfPrintSettings settings; @@ -1096,9 +1114,25 @@ CefPdfPrintSettings GetJNIPdfPrintSettings(JNIEnv* env, jobject obj) { tmp.clear(); } + GetJNIFieldBoolean(env, cls, obj, "generate_tagged_pdf", + &settings.generate_tagged_pdf); + + GetJNIFieldBoolean(env, cls, obj, "generate_document_outline", + &settings.generate_document_outline); + return settings; } +// JNI CefRegistration object. +class ScopedJNIRegistration : public ScopedJNIObject { + public: + ScopedJNIRegistration(JNIEnv* env, CefRefPtr obj) + : ScopedJNIObject(env, + obj, + "org/cef/browser/CefRegistration_N", + "CefRegistration") {} +}; + } // namespace JNIEXPORT jboolean JNICALL @@ -1109,9 +1143,10 @@ Java_org_cef_browser_CefBrowser_1N_N_1CreateBrowser(JNIEnv* env, jstring url, jboolean osr, jboolean transparent, - jobject jcontext) { + jobject jcontext, + jobject browserSettings) { std::shared_ptr objs(new JNIObjectsForCreate( - env, jbrowser, nullptr, jclientHandler, url, jcontext, nullptr)); + env, jbrowser, nullptr, jclientHandler, url, jcontext, nullptr, browserSettings)); if (CefCurrentlyOn(TID_UI)) { create(objs, windowHandle, osr, transparent); } else { @@ -1132,7 +1167,7 @@ Java_org_cef_browser_CefBrowser_1N_N_1CreateDevTools(JNIEnv* env, jobject inspect) { std::shared_ptr objs( new JNIObjectsForCreate(env, jbrowser, jparent, jclientHandler, nullptr, - nullptr, inspect)); + nullptr, inspect, nullptr)); if (CefCurrentlyOn(TID_UI)) { create(objs, windowHandle, osr, transparent); } else { @@ -1142,6 +1177,52 @@ Java_org_cef_browser_CefBrowser_1N_N_1CreateDevTools(JNIEnv* env, return JNI_FALSE; // set asynchronously } +JNIEXPORT void JNICALL +Java_org_cef_browser_CefBrowser_1N_N_1ExecuteDevToolsMethod( + JNIEnv* env, + jobject jbrowser, + jstring method, + jstring parametersAsJson, + jobject jcallback) { + CefRefPtr callback = new IntCallback(env, jcallback); + + CefRefPtr browser = GetJNIBrowser(env, jbrowser); + if (!browser.get()) { + callback->onComplete(0); + return; + } + + CefString strMethod = GetJNIString(env, method); + CefString strParametersAsJson = GetJNIString(env, parametersAsJson); + + if (CefCurrentlyOn(TID_UI)) { + executeDevToolsMethod(browser->GetHost(), strMethod, strParametersAsJson, + callback); + } else { + CefPostTask(TID_UI, + base::BindOnce(executeDevToolsMethod, browser->GetHost(), + strMethod, strParametersAsJson, callback)); + } +} + +JNIEXPORT jobject JNICALL +Java_org_cef_browser_CefBrowser_1N_N_1AddDevToolsMessageObserver( + JNIEnv* env, + jobject jbrowser, + jobject jobserver) { + CefRefPtr browser = + JNI_GET_BROWSER_OR_RETURN(env, jbrowser, NULL); + + CefRefPtr observer = + new DevToolsMessageObserver(env, jobserver); + + CefRefPtr registration = + browser->GetHost()->AddDevToolsMessageObserver(observer); + + ScopedJNIRegistration jregistration(env, registration); + return jregistration.Release(); +} + JNIEXPORT jlong JNICALL Java_org_cef_browser_CefBrowser_1N_N_1GetWindowHandle(JNIEnv* env, jobject obj, @@ -1237,11 +1318,12 @@ Java_org_cef_browser_CefBrowser_1N_N_1GetFocusedFrame(JNIEnv* env, } JNIEXPORT jobject JNICALL -Java_org_cef_browser_CefBrowser_1N_N_1GetFrame(JNIEnv* env, - jobject obj, - jlong identifier) { +Java_org_cef_browser_CefBrowser_1N_N_1GetFrameByIdentifier(JNIEnv* env, + jobject obj, + jstring identifier) { CefRefPtr browser = JNI_GET_BROWSER_OR_RETURN(env, obj, nullptr); - CefRefPtr frame = browser->GetFrame(identifier); + CefRefPtr frame = + browser->GetFrameByIdentifier(GetJNIString(env, identifier)); if (!frame) return nullptr; ScopedJNIFrame jframe(env, frame); @@ -1249,11 +1331,11 @@ Java_org_cef_browser_CefBrowser_1N_N_1GetFrame(JNIEnv* env, } JNIEXPORT jobject JNICALL -Java_org_cef_browser_CefBrowser_1N_N_1GetFrame2(JNIEnv* env, - jobject obj, - jstring name) { +Java_org_cef_browser_CefBrowser_1N_N_1GetFrameByName(JNIEnv* env, + jobject obj, + jstring name) { CefRefPtr browser = JNI_GET_BROWSER_OR_RETURN(env, obj, nullptr); - CefRefPtr frame = browser->GetFrame(GetJNIString(env, name)); + CefRefPtr frame = browser->GetFrameByName(GetJNIString(env, name)); if (!frame) return nullptr; ScopedJNIFrame jframe(env, frame); @@ -1270,9 +1352,9 @@ JNIEXPORT jobject JNICALL Java_org_cef_browser_CefBrowser_1N_N_1GetFrameIdentifiers(JNIEnv* env, jobject obj) { CefRefPtr browser = JNI_GET_BROWSER_OR_RETURN(env, obj, nullptr); - std::vector identifiers; + std::vector identifiers; browser->GetFrameIdentifiers(identifiers); - return NewJNILongVector(env, identifiers); + return NewJNIStringVector(env, identifiers); } JNIEXPORT jobject JNICALL @@ -1994,3 +2076,38 @@ Java_org_cef_browser_CefBrowser_1N_N_1NotifyMoveOrResizeStarted(JNIEnv* env, } #endif } + +JNIEXPORT void JNICALL +Java_org_cef_browser_CefBrowser_1N_N_1SetWindowlessFrameRate(JNIEnv* env, + jobject jbrowser, + jint frameRate) { + CefRefPtr browser = JNI_GET_BROWSER_OR_RETURN(env, jbrowser); + CefRefPtr host = browser->GetHost(); + host->SetWindowlessFrameRate(frameRate); +} + +void getWindowlessFrameRate(CefRefPtr host, + CefRefPtr callback) { + callback->onComplete((jint)host->GetWindowlessFrameRate()); +} + +JNIEXPORT void JNICALL +Java_org_cef_browser_CefBrowser_1N_N_1GetWindowlessFrameRate( + JNIEnv* env, + jobject jbrowser, + jobject jintCallback) { + CefRefPtr callback = new IntCallback(env, jintCallback); + + CefRefPtr browser = GetJNIBrowser(env, jbrowser); + if (!browser.get()) { + callback->onComplete(0); + return; + } + + CefRefPtr host = browser->GetHost(); + if (CefCurrentlyOn(TID_UI)) { + getWindowlessFrameRate(host, callback); + } else { + CefPostTask(TID_UI, base::BindOnce(getWindowlessFrameRate, host, callback)); + } +} diff --git a/native/CefBrowser_N.h b/native/CefBrowser_N.h index bd0fd0d0..32548e84 100644 --- a/native/CefBrowser_N.h +++ b/native/CefBrowser_N.h @@ -11,7 +11,7 @@ extern "C" { * Class: org_cef_browser_CefBrowser_N * Method: N_CreateBrowser * Signature: - * (Lorg/cef/handler/CefClientHandler;JLjava/lang/String;ZZLjava/awt/Component;Lorg/cef/browser/CefRequestContext;)Z + * (Lorg/cef/handler/CefClientHandler;JLjava/lang/String;ZZLjava/awt/Component;Lorg/cef/browser/CefRequestContext;Lorg/cef/CefBrowserSettings;)Z */ JNIEXPORT jboolean JNICALL Java_org_cef_browser_CefBrowser_1N_N_1CreateBrowser(JNIEnv*, @@ -21,6 +21,8 @@ Java_org_cef_browser_CefBrowser_1N_N_1CreateBrowser(JNIEnv*, jstring, jboolean, jboolean, + jobject, + jobject, jobject); /* @@ -39,6 +41,30 @@ Java_org_cef_browser_CefBrowser_1N_N_1CreateDevTools(JNIEnv*, jboolean, jobject); +/* + * Class: org_cef_browser_CefBrowser_N + * Method: N_ExecuteDevToolsMethod + * Signature: + * (Ljava/lang/String;Ljava/lang/String;Lorg/cef/browser/CefBrowser_N/IntCallback;)V + */ +JNIEXPORT void JNICALL +Java_org_cef_browser_CefBrowser_1N_N_1ExecuteDevToolsMethod(JNIEnv*, + jobject, + jstring, + jstring, + jobject); + +/* + * Class: org_cef_browser_CefBrowser_N + * Method: N_AddDevToolsMessageObserver + * Signature: + * (Lorg/cef/browser/CefDevToolsMessageObserver;)Lorg/cef/browser/CefRegistration; + */ +JNIEXPORT jobject JNICALL +Java_org_cef_browser_CefBrowser_1N_N_1AddDevToolsMessageObserver(JNIEnv*, + jobject, + jobject); + /* * Class: org_cef_browser_CefBrowser_N * Method: N_GetWindowHandle @@ -137,19 +163,21 @@ Java_org_cef_browser_CefBrowser_1N_N_1GetFocusedFrame(JNIEnv*, jobject); /* * Class: org_cef_browser_CefBrowser_N - * Method: N_GetFrame - * Signature: (J)Lorg/cef/browser/CefFrame; + * Method: N_GetFrameByIdentifier + * Signature: (Ljava/lang/String;)Lorg/cef/browser/CefFrame; */ JNIEXPORT jobject JNICALL -Java_org_cef_browser_CefBrowser_1N_N_1GetFrame(JNIEnv*, jobject, jlong); +Java_org_cef_browser_CefBrowser_1N_N_1GetFrameByIdentifier(JNIEnv*, + jobject, + jstring); /* * Class: org_cef_browser_CefBrowser_N - * Method: N_GetFrame2 + * Method: N_GetFrameByName * Signature: (Ljava/lang/String;)Lorg/cef/browser/CefFrame; */ JNIEXPORT jobject JNICALL -Java_org_cef_browser_CefBrowser_1N_N_1GetFrame2(JNIEnv*, jobject, jstring); +Java_org_cef_browser_CefBrowser_1N_N_1GetFrameByName(JNIEnv*, jobject, jstring); /* * Class: org_cef_browser_CefBrowser_N @@ -346,7 +374,7 @@ Java_org_cef_browser_CefBrowser_1N_N_1PrintToPDF(JNIEnv*, /* * Class: org_cef_browser_CefBrowser_N * Method: N_Find - * Signature: (ILjava/lang/String;ZZZ)V + * Signature: (Ljava/lang/String;ZZZ)V */ JNIEXPORT void JNICALL Java_org_cef_browser_CefBrowser_1N_N_1Find(JNIEnv*, jobject, @@ -508,6 +536,37 @@ JNIEXPORT void JNICALL Java_org_cef_browser_CefBrowser_1N_N_1NotifyMoveOrResizeStarted(JNIEnv*, jobject); +/* + * Class: org_cef_browser_CefBrowser_N + * Method: N_SetWindowlessFrameRate + * Signature: (I)V + */ +JNIEXPORT void JNICALL +Java_org_cef_browser_CefBrowser_1N_N_1SetWindowlessFrameRate(JNIEnv*, + jobject, + jint); + +/* + * Class: org_cef_browser_CefBrowser_N + * Method: N_GetWindowlessFrameRate + * Signature: (Lorg/cef/browser/CefBrowser_N/IntCallback;)V + */ +JNIEXPORT void JNICALL +Java_org_cef_browser_CefBrowser_1N_N_1GetWindowlessFrameRate(JNIEnv*, + jobject, + jobject); + +#ifdef __cplusplus +} +#endif +#endif +/* Header for class org_cef_browser_CefBrowser_N_IntCallback */ + +#ifndef _Included_org_cef_browser_CefBrowser_N_IntCallback +#define _Included_org_cef_browser_CefBrowser_N_IntCallback +#ifdef __cplusplus +extern "C" { +#endif #ifdef __cplusplus } #endif diff --git a/native/CefFileDialogCallback_N.h b/native/CefFileDialogCallback_N.h index 1f11dae9..1da3ded8 100644 --- a/native/CefFileDialogCallback_N.h +++ b/native/CefFileDialogCallback_N.h @@ -10,13 +10,12 @@ extern "C" { /* * Class: org_cef_callback_CefFileDialogCallback_N * Method: N_Continue - * Signature: (JILjava/util/Vector;)V + * Signature: (JLjava/util/Vector;)V */ JNIEXPORT void JNICALL Java_org_cef_callback_CefFileDialogCallback_1N_N_1Continue(JNIEnv*, jobject, jlong, - jint, jobject); /* diff --git a/native/CefFrame_N.cpp b/native/CefFrame_N.cpp index 3fc93790..cab338ed 100644 --- a/native/CefFrame_N.cpp +++ b/native/CefFrame_N.cpp @@ -27,14 +27,14 @@ JNIEXPORT void JNICALL Java_org_cef_browser_CefFrame_1N_N_1Dispose(JNIEnv* env, ClearSelf(env, obj); } -JNIEXPORT jlong JNICALL +JNIEXPORT jstring JNICALL Java_org_cef_browser_CefFrame_1N_N_1GetIdentifier(JNIEnv* env, jobject obj, jlong self) { CefRefPtr frame = GetSelf(self); if (!frame) - return (jlong)-1; - return (jlong)frame->GetIdentifier(); + return nullptr; + return NewJNIString(env, frame->GetIdentifier()); } JNIEXPORT jstring JNICALL @@ -164,3 +164,14 @@ JNIEXPORT void JNICALL Java_org_cef_browser_CefFrame_1N_N_1Paste(JNIEnv* env, frame->Paste(); } + +JNIEXPORT void JNICALL +Java_org_cef_browser_CefFrame_1N_N_1SelectAll(JNIEnv* env, + jobject obj, + jlong self) { + CefRefPtr frame = GetSelf(self); + if (!frame) + return; + + frame->SelectAll(); +} diff --git a/native/CefFrame_N.h b/native/CefFrame_N.h index e1f6b459..a1568181 100644 --- a/native/CefFrame_N.h +++ b/native/CefFrame_N.h @@ -19,9 +19,9 @@ JNIEXPORT void JNICALL Java_org_cef_browser_CefFrame_1N_N_1Dispose(JNIEnv*, /* * Class: org_cef_browser_CefFrame_N * Method: N_GetIdentifier - * Signature: (J)J + * Signature: (J)Ljava/lang/String; */ -JNIEXPORT jlong JNICALL +JNIEXPORT jstring JNICALL Java_org_cef_browser_CefFrame_1N_N_1GetIdentifier(JNIEnv*, jobject, jlong); /* @@ -135,6 +135,15 @@ JNIEXPORT void JNICALL Java_org_cef_browser_CefFrame_1N_N_1Paste(JNIEnv*, jobject, jlong); +/* + * Class: org_cef_browser_CefFrame_N + * Method: N_SelectAll + * Signature: (J)V + */ +JNIEXPORT void JNICALL Java_org_cef_browser_CefFrame_1N_N_1SelectAll(JNIEnv*, + jobject, + jlong); + #ifdef __cplusplus } #endif diff --git a/native/CefRegistration_N.cpp b/native/CefRegistration_N.cpp new file mode 100644 index 00000000..dc23751d --- /dev/null +++ b/native/CefRegistration_N.cpp @@ -0,0 +1,14 @@ +// Copyright (c) 2024 The Chromium Embedded Framework Authors. All rights +// reserved. Use of this source code is governed by a BSD-style license that +// can be found in the LICENSE file. + +#include "CefRegistration_N.h" +#include "include/cef_registration.h" +#include "jni_scoped_helpers.h" + +JNIEXPORT void JNICALL +Java_org_cef_browser_CefRegistration_1N_N_1Dispose(JNIEnv* env, + jobject obj, + jlong self) { + SetCefForJNIObject(env, obj, NULL, "CefRegistration"); +} diff --git a/native/CefRegistration_N.h b/native/CefRegistration_N.h new file mode 100644 index 00000000..9747b04b --- /dev/null +++ b/native/CefRegistration_N.h @@ -0,0 +1,21 @@ +/* DO NOT EDIT THIS FILE - it is machine generated */ +#include +/* Header for class org_cef_browser_CefRegistration_N */ + +#ifndef _Included_org_cef_browser_CefRegistration_N +#define _Included_org_cef_browser_CefRegistration_N +#ifdef __cplusplus +extern "C" { +#endif +/* + * Class: org_cef_browser_CefRegistration_N + * Method: N_Dispose + * Signature: (J)V + */ +JNIEXPORT void JNICALL +Java_org_cef_browser_CefRegistration_1N_N_1Dispose(JNIEnv*, jobject, jlong); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/native/browser_process_handler.cpp b/native/browser_process_handler.cpp index 38c8fdca..ad583e87 100644 --- a/native/browser_process_handler.cpp +++ b/native/browser_process_handler.cpp @@ -50,6 +50,31 @@ void BrowserProcessHandler::OnScheduleMessagePumpWork(int64_t delay_ms) { delay_ms); } +bool BrowserProcessHandler::OnAlreadyRunningAppRelaunch( + CefRefPtr command_line, + const CefString& current_directory) { + if (!handle_) + return false; + + ScopedJNIEnv env; + if (!env) + return false; + + ScopedJNIObject jcommandLine( + env, command_line, "org/cef/callback/CefCommandLine_N", "CefCommandLine"); + jcommandLine.SetTemporary(); + ScopedJNIString jcurrentDirectory(env, current_directory); + + jboolean jresult = 0; + + JNI_CALL_BOOLEAN_METHOD( + jresult, env, handle_, "onAlreadyRunningAppRelaunch", + "(Lorg/cef/callback/CefCommandLine;Ljava/lang/String;)Z", + jcommandLine.get(), jcurrentDirectory.get()); + + return jresult; +} + // static CefRefPtr BrowserProcessHandler::GetMessageRouterConfigs() { int idx = 0; diff --git a/native/browser_process_handler.h b/native/browser_process_handler.h index 260ebd66..8bbf29e3 100644 --- a/native/browser_process_handler.h +++ b/native/browser_process_handler.h @@ -34,6 +34,8 @@ class BrowserProcessHandler : public CefBrowserProcessHandler { void OnContextInitialized() override; void OnScheduleMessagePumpWork(int64_t delay_ms) override; + bool OnAlreadyRunningAppRelaunch(CefRefPtr command_line, + const CefString& current_directory) override; static CefRefPtr GetMessageRouterConfigs(); static void AddMessageRouterConfig(const CefMessageRouterConfig& cfg); diff --git a/native/context.cpp b/native/context.cpp index b47a3956..1e4020c1 100644 --- a/native/context.cpp +++ b/native/context.cpp @@ -44,6 +44,11 @@ CefSettings GetJNISettings(JNIEnv* env, jobject obj) { CefString(&settings.cache_path) = tmp; tmp.clear(); } + if (GetJNIFieldString(env, cls, obj, "root_cache_path", &tmp) && + !tmp.empty()) { + CefString(&settings.root_cache_path) = tmp; + tmp.clear(); + } GetJNIFieldBoolean(env, cls, obj, "persist_session_cookies", &settings.persist_session_cookies); if (GetJNIFieldString(env, cls, obj, "user_agent", &tmp) && !tmp.empty()) { diff --git a/native/devtools_message_observer.cpp b/native/devtools_message_observer.cpp new file mode 100644 index 00000000..84a47fbf --- /dev/null +++ b/native/devtools_message_observer.cpp @@ -0,0 +1,44 @@ +// Copyright (c) 2024 The Chromium Embedded Framework Authors. All rights +// reserved. Use of this source code is governed by a BSD-style license that +// can be found in the LICENSE file. + +#include "devtools_message_observer.h" + +#include "jni_util.h" + +DevToolsMessageObserver::DevToolsMessageObserver(JNIEnv* env, jobject observer) + : handle_(env, observer) {} + +void DevToolsMessageObserver::OnDevToolsMethodResult( + CefRefPtr browser, + int message_id, + bool success, + const void* result, + size_t result_size) { + ScopedJNIEnv env; + if (!env) + return; + + ScopedJNIBrowser jbrowser(env, browser); + std::string strResult(static_cast(result), result_size); + JNI_CALL_VOID_METHOD( + env, handle_, "onDevToolsMethodResult", + "(Lorg/cef/browser/CefBrowser;IZLjava/lang/String;)V", jbrowser.get(), + message_id, success ? JNI_TRUE : JNI_FALSE, NewJNIString(env, strResult)); +} + +void DevToolsMessageObserver::OnDevToolsEvent(CefRefPtr browser, + const CefString& method, + const void* params, + size_t params_size) { + ScopedJNIEnv env; + if (!env) + return; + ScopedJNIBrowser jbrowser(env, browser); + + std::string strParams(static_cast(params), params_size); + JNI_CALL_VOID_METHOD( + env, handle_, "onDevToolsEvent", + "(Lorg/cef/browser/CefBrowser;Ljava/lang/String;Ljava/lang/String;)V", + jbrowser.get(), NewJNIString(env, method), NewJNIString(env, strParams)); +} diff --git a/native/devtools_message_observer.h b/native/devtools_message_observer.h new file mode 100644 index 00000000..19e34bb9 --- /dev/null +++ b/native/devtools_message_observer.h @@ -0,0 +1,37 @@ +// Copyright (c) 2024 The Chromium Embedded Framework Authors. All rights +// reserved. Use of this source code is governed by a BSD-style license that +// can be found in the LICENSE file. + +#ifndef JCEF_NATIVE_DEVTOOLS_MESSAGE_OBSERVER_H_ +#define JCEF_NATIVE_DEVTOOLS_MESSAGE_OBSERVER_H_ +#pragma once + +#include +#include "include/cef_devtools_message_observer.h" + +#include "jni_scoped_helpers.h" + +// DevToolsMessageObserver implementation. +class DevToolsMessageObserver : public CefDevToolsMessageObserver { + public: + DevToolsMessageObserver(JNIEnv* env, jobject observer); + + // CefDevToolsMessageObserver methods + virtual void OnDevToolsMethodResult(CefRefPtr browser, + int message_id, + bool success, + const void* result, + size_t result_size) override; + virtual void OnDevToolsEvent(CefRefPtr browser, + const CefString& method, + const void* params, + size_t params_size) override; + + protected: + ScopedJNIObjectGlobal handle_; + + // Include the default reference counting implementation. + IMPLEMENT_REFCOUNTING(DevToolsMessageObserver); +}; + +#endif // JCEF_NATIVE_DEVTOOLS_MESSAGE_OBSERVER_H_ diff --git a/native/dialog_handler.cpp b/native/dialog_handler.cpp index 30acb467..883f675f 100644 --- a/native/dialog_handler.cpp +++ b/native/dialog_handler.cpp @@ -27,12 +27,15 @@ class ScopedJNIFileDialogCallback DialogHandler::DialogHandler(JNIEnv* env, jobject handler) : handle_(env, handler) {} -bool DialogHandler::OnFileDialog(CefRefPtr browser, - FileDialogMode mode, - const CefString& title, - const CefString& default_file_path, - const std::vector& accept_filters, - CefRefPtr callback) { +bool DialogHandler::OnFileDialog( + CefRefPtr browser, + FileDialogMode mode, + const CefString& title, + const CefString& default_file_path, + const std::vector& accept_filters, + const std::vector& accept_extensions, + const std::vector& accept_descriptions, + CefRefPtr callback) { ScopedJNIEnv env; if (!env) return false; @@ -42,6 +45,10 @@ bool DialogHandler::OnFileDialog(CefRefPtr browser, ScopedJNIString jdefaultFilePath(env, default_file_path); ScopedJNIObjectLocal jacceptFilters(env, NewJNIStringVector(env, accept_filters)); + ScopedJNIObjectLocal jacceptExtensions( + env, NewJNIStringVector(env, accept_extensions)); + ScopedJNIObjectLocal jacceptDescriptions( + env, NewJNIStringVector(env, accept_descriptions)); ScopedJNIFileDialogCallback jcallback(env, callback); ScopedJNIObjectResult jmode(env); @@ -61,9 +68,11 @@ bool DialogHandler::OnFileDialog(CefRefPtr browser, env, handle_, "onFileDialog", "(Lorg/cef/browser/CefBrowser;Lorg/cef/handler/" "CefDialogHandler$FileDialogMode;Ljava/lang/String;Ljava/lang/" - "String;Ljava/util/Vector;Lorg/cef/callback/CefFileDialogCallback;)Z", + "String;Ljava/util/Vector;Ljava/util/Vector;Ljava/util/Vector;Lorg/cef/" + "callback/CefFileDialogCallback;)Z", Boolean, jreturn, jbrowser.get(), jmode.get(), jtitle.get(), - jdefaultFilePath.get(), jacceptFilters.get(), jcallback.get()); + jdefaultFilePath.get(), jacceptFilters.get(), jacceptExtensions.get(), + jacceptDescriptions.get(), jcallback.get()); if (jreturn == JNI_FALSE) { // If the Java method returns "false" the callback won't be used and diff --git a/native/dialog_handler.h b/native/dialog_handler.h index d4ec0cd3..0a5411ee 100644 --- a/native/dialog_handler.h +++ b/native/dialog_handler.h @@ -22,6 +22,8 @@ class DialogHandler : public CefDialogHandler { const CefString& title, const CefString& default_file_path, const std::vector& accept_filters, + const std::vector& accept_extensions, + const std::vector& accept_descriptions, CefRefPtr callback) override; protected: diff --git a/native/display_handler.cpp b/native/display_handler.cpp index 60874291..cb0537fa 100644 --- a/native/display_handler.cpp +++ b/native/display_handler.cpp @@ -41,6 +41,18 @@ void DisplayHandler::OnTitleChange(CefRefPtr browser, jbrowser.get(), jtitle.get()); } +void DisplayHandler::OnFullscreenModeChange(CefRefPtr browser, + bool fullscreen) { + ScopedJNIEnv env; + if (!env) + return; + + ScopedJNIBrowser jbrowser(env, browser); + JNI_CALL_VOID_METHOD(env, handle_, "onFullscreenModeChange", + "(Lorg/cef/browser/CefBrowser;Z)V", jbrowser.get(), + (jboolean)fullscreen); +} + bool DisplayHandler::OnTooltip(CefRefPtr browser, CefString& text) { ScopedJNIEnv env; if (!env) diff --git a/native/display_handler.h b/native/display_handler.h index 3b015b62..30615fdb 100644 --- a/native/display_handler.h +++ b/native/display_handler.h @@ -23,6 +23,8 @@ class DisplayHandler : public CefDisplayHandler { const CefString& url) override; void OnTitleChange(CefRefPtr browser, const CefString& title) override; + void OnFullscreenModeChange(CefRefPtr browser, + bool fullscreen) override; bool OnTooltip(CefRefPtr browser, CefString& text) override; void OnStatusMessage(CefRefPtr browser, const CefString& value) override; diff --git a/native/download_handler.cpp b/native/download_handler.cpp index f594d435..e0b37759 100644 --- a/native/download_handler.cpp +++ b/native/download_handler.cpp @@ -49,14 +49,14 @@ class ScopedJNIDownloadItemCallback DownloadHandler::DownloadHandler(JNIEnv* env, jobject handler) : handle_(env, handler) {} -void DownloadHandler::OnBeforeDownload( +bool DownloadHandler::OnBeforeDownload( CefRefPtr browser, CefRefPtr download_item, const CefString& suggested_name, CefRefPtr callback) { ScopedJNIEnv env; if (!env) - return; + return false; ScopedJNIBrowser jbrowser(env, browser); ScopedJNIDownloadItem jdownloadItem(env, download_item); @@ -64,12 +64,16 @@ void DownloadHandler::OnBeforeDownload( ScopedJNIString jsuggestedName(env, suggested_name); ScopedJNIBeforeDownloadCallback jcallback(env, callback); - JNI_CALL_VOID_METHOD( - env, handle_, "onBeforeDownload", + jboolean jresult = 0; + + JNI_CALL_BOOLEAN_METHOD( + jresult, env, handle_, "onBeforeDownload", "(Lorg/cef/browser/CefBrowser;Lorg/cef/callback/CefDownloadItem;" - "Ljava/lang/String;Lorg/cef/callback/CefBeforeDownloadCallback;)V", + "Ljava/lang/String;Lorg/cef/callback/CefBeforeDownloadCallback;)Z", jbrowser.get(), jdownloadItem.get(), jsuggestedName.get(), jcallback.get()); + + return jresult; } void DownloadHandler::OnDownloadUpdated( diff --git a/native/download_handler.h b/native/download_handler.h index d41ca492..adbaacbb 100644 --- a/native/download_handler.h +++ b/native/download_handler.h @@ -17,7 +17,7 @@ class DownloadHandler : public CefDownloadHandler { DownloadHandler(JNIEnv* env, jobject handler); // CefDownloadHandler methods - virtual void OnBeforeDownload( + virtual bool OnBeforeDownload( CefRefPtr browser, CefRefPtr download_item, const CefString& suggested_name, diff --git a/native/int_callback.cpp b/native/int_callback.cpp new file mode 100644 index 00000000..a45471a4 --- /dev/null +++ b/native/int_callback.cpp @@ -0,0 +1,20 @@ +// Copyright (c) 2024 The Chromium Embedded Framework Authors. All rights +// reserved. Use of this source code is governed by a BSD-style license that +// can be found in the LICENSE file. + +#include "int_callback.h" + +#include "jni_scoped_helpers.h" +#include "jni_util.h" +#include "util.h" + +IntCallback::IntCallback(JNIEnv* env, jobject jcallback) + : handle_(env, jcallback) {} + +void IntCallback::onComplete(int value) { + ScopedJNIEnv env; + if (!env) + return; + + JNI_CALL_VOID_METHOD(env, handle_, "onComplete", "(I)V", (jint)value); +} diff --git a/native/int_callback.h b/native/int_callback.h new file mode 100644 index 00000000..6437479c --- /dev/null +++ b/native/int_callback.h @@ -0,0 +1,28 @@ +// Copyright (c) 2024 The Chromium Embedded Framework Authors. All rights +// reserved. Use of this source code is governed by a BSD-style license that +// can be found in the LICENSE file. + +#ifndef JCEF_NATIVE_INT_CALLBACK_H_ +#define JCEF_NATIVE_INT_CALLBACK_H_ +#pragma once + +#include + +#include "jni_scoped_helpers.h" + +// Callback for returning int primatives. The methods of +// this class will be called on the browser process UI thread. +class IntCallback : public virtual CefBaseRefCounted { + public: + IntCallback(JNIEnv* env, jobject jcallback); + + virtual void onComplete(int value); + + protected: + ScopedJNIObjectGlobal handle_; + + // Include the default reference counting implementation. + IMPLEMENT_REFCOUNTING(IntCallback); +}; + +#endif // JCEF_NATIVE_INT_CALLBACK_H_ diff --git a/native/jni_util.cpp b/native/jni_util.cpp index 9aacfd59..11f5d684 100644 --- a/native/jni_util.cpp +++ b/native/jni_util.cpp @@ -632,18 +632,10 @@ jobject NewJNIErrorCode(JNIEnv* env, cef_errorcode_t errorCode) { ERR_CONTENT_DECODING_INIT_FAILED, jerrorCode); JNI_CASE(env, "org/cef/handler/CefLoadHandler$ErrorCode", ERR_HTTP2_RST_STREAM_NO_ERROR_RECEIVED, jerrorCode); - JNI_CASE(env, "org/cef/handler/CefLoadHandler$ErrorCode", - ERR_HTTP2_PUSHED_STREAM_NOT_AVAILABLE, jerrorCode); - JNI_CASE(env, "org/cef/handler/CefLoadHandler$ErrorCode", - ERR_HTTP2_CLAIMED_PUSHED_STREAM_RESET_BY_SERVER, jerrorCode); JNI_CASE(env, "org/cef/handler/CefLoadHandler$ErrorCode", ERR_TOO_MANY_RETRIES, jerrorCode); JNI_CASE(env, "org/cef/handler/CefLoadHandler$ErrorCode", ERR_HTTP2_STREAM_CLOSED, jerrorCode); - JNI_CASE(env, "org/cef/handler/CefLoadHandler$ErrorCode", - ERR_HTTP2_CLIENT_REFUSED_STREAM, jerrorCode); - JNI_CASE(env, "org/cef/handler/CefLoadHandler$ErrorCode", - ERR_HTTP2_PUSHED_RESPONSE_DOES_NOT_MATCH, jerrorCode); JNI_CASE(env, "org/cef/handler/CefLoadHandler$ErrorCode", ERR_HTTP_RESPONSE_CODE_FAILURE, jerrorCode); JNI_CASE(env, "org/cef/handler/CefLoadHandler$ErrorCode", @@ -693,20 +685,6 @@ jobject NewJNIErrorCode(JNIEnv* env, cef_errorcode_t errorCode) { JNI_CASE(env, "org/cef/handler/CefLoadHandler$ErrorCode", ERR_TRUST_TOKEN_OPERATION_SUCCESS_WITHOUT_SENDING_REQUEST, jerrorCode); - JNI_CASE(env, "org/cef/handler/CefLoadHandler$ErrorCode", ERR_FTP_FAILED, - jerrorCode); - JNI_CASE(env, "org/cef/handler/CefLoadHandler$ErrorCode", - ERR_FTP_SERVICE_UNAVAILABLE, jerrorCode); - JNI_CASE(env, "org/cef/handler/CefLoadHandler$ErrorCode", - ERR_FTP_TRANSFER_ABORTED, jerrorCode); - JNI_CASE(env, "org/cef/handler/CefLoadHandler$ErrorCode", - ERR_FTP_FILE_BUSY, jerrorCode); - JNI_CASE(env, "org/cef/handler/CefLoadHandler$ErrorCode", - ERR_FTP_SYNTAX_ERROR, jerrorCode); - JNI_CASE(env, "org/cef/handler/CefLoadHandler$ErrorCode", - ERR_FTP_COMMAND_NOT_SUPPORTED, jerrorCode); - JNI_CASE(env, "org/cef/handler/CefLoadHandler$ErrorCode", - ERR_FTP_BAD_COMMAND_SEQUENCE, jerrorCode); JNI_CASE(env, "org/cef/handler/CefLoadHandler$ErrorCode", ERR_PKCS12_IMPORT_BAD_PASSWORD, jerrorCode); JNI_CASE(env, "org/cef/handler/CefLoadHandler$ErrorCode", diff --git a/native/request_handler.cpp b/native/request_handler.cpp index 9d6b89e3..9dee9799 100644 --- a/native/request_handler.cpp +++ b/native/request_handler.cpp @@ -120,8 +120,8 @@ bool RequestHandler::GetAuthCredentials(CefRefPtr browser, ScopedJNIBrowser jbrowser(env, browser); ScopedJNIString joriginUrl(env, origin_url); ScopedJNIString jhost(env, host); - ScopedJNIString jrealm(env, host); - ScopedJNIString jscheme(env, host); + ScopedJNIString jrealm(env, realm); + ScopedJNIString jscheme(env, scheme); ScopedJNIAuthCallback jcallback(env, callback); jboolean jresult = JNI_FALSE; @@ -175,7 +175,9 @@ bool RequestHandler::OnCertificateError(CefRefPtr browser, } void RequestHandler::OnRenderProcessTerminated(CefRefPtr browser, - TerminationStatus status) { + TerminationStatus status, + int error_code, + const CefString& error_string) { // Forward request to ClientHandler to make the message_router_ happy. CefRefPtr client = (ClientHandler*)browser->GetHost()->GetClient().get(); @@ -197,11 +199,17 @@ void RequestHandler::OnRenderProcessTerminated(CefRefPtr browser, TS_PROCESS_CRASHED, jstatus); JNI_CASE(env, "org/cef/handler/CefRequestHandler$TerminationStatus", TS_PROCESS_OOM, jstatus); + JNI_CASE(env, "org/cef/handler/CefRequestHandler$TerminationStatus", + TS_LAUNCH_FAILED, jstatus); + JNI_CASE(env, "org/cef/handler/CefRequestHandler$TerminationStatus", + TS_INTEGRITY_FAILURE, jstatus); } + ScopedJNIString jerrorString(env, error_string); + JNI_CALL_VOID_METHOD( env, handle_, "onRenderProcessTerminated", "(Lorg/cef/browser/CefBrowser;" "Lorg/cef/handler/CefRequestHandler$TerminationStatus;)V", - jbrowser.get(), jstatus.get()); + jbrowser.get(), jstatus.get(), error_code, jerrorString.get()); } diff --git a/native/request_handler.h b/native/request_handler.h index 60b47b0b..9ee8356e 100644 --- a/native/request_handler.h +++ b/native/request_handler.h @@ -50,7 +50,9 @@ class RequestHandler : public CefRequestHandler { CefRefPtr ssl_info, CefRefPtr callback) override; void OnRenderProcessTerminated(CefRefPtr browser, - TerminationStatus status) override; + TerminationStatus status, + int error_code, + const CefString& error_string) override; protected: ScopedJNIObjectGlobal handle_; diff --git a/tools/make_all_jni_headers.bat b/tools/make_all_jni_headers.bat index 3f101d3a..ecb1dee0 100644 --- a/tools/make_all_jni_headers.bat +++ b/tools/make_all_jni_headers.bat @@ -37,6 +37,7 @@ call make_jni_header.bat %1 org.cef.callback.CefQueryCallback_N call make_jni_header.bat %1 org.cef.callback.CefSchemeRegistrar_N call make_jni_header.bat %1 org.cef.handler.CefClientHandler call make_jni_header.bat %1 org.cef.misc.CefPrintSettings_N +call make_jni_header.bat %1 org.cef.browser.CefRegistration_N call make_jni_header.bat %1 org.cef.network.CefCookieManager_N call make_jni_header.bat %1 org.cef.network.CefPostData_N call make_jni_header.bat %1 org.cef.network.CefPostDataElement_N From cb159805e1d5a045d03a2f4d2d61e2b7679b8703 Mon Sep 17 00:00:00 2001 From: ds58 <30220598+ds58@users.noreply.github.com> Date: Fri, 4 Oct 2024 18:21:17 -0500 Subject: [PATCH 75/75] Update build-jcef.yml --- .github/workflows/build-jcef.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-jcef.yml b/.github/workflows/build-jcef.yml index 95349ce3..eb9a667a 100644 --- a/.github/workflows/build-jcef.yml +++ b/.github/workflows/build-jcef.yml @@ -1,4 +1,4 @@ -name: Build java-cef 5359 +name: Build java-cef on: push: