diff options
Diffstat (limited to 'java')
-rw-r--r-- | java/org/cef/CefClient.java | 41 | ||||
-rw-r--r-- | java/org/cef/browser/CefBrowser.java | 25 | ||||
-rw-r--r-- | java/org/cef/browser/CefBrowserOsr.java | 275 | ||||
-rw-r--r-- | java/org/cef/browser/CefBrowserWr.java | 7 | ||||
-rw-r--r-- | java/org/cef/browser/CefBrowser_N.java | 2 | ||||
-rw-r--r-- | java/org/cef/browser/CefRenderer.java | 4 | ||||
-rw-r--r-- | java/org/cef/handler/CefDisplayHandler.java | 25 | ||||
-rw-r--r-- | java/org/cef/handler/CefDisplayHandlerAdapter.java | 7 | ||||
-rw-r--r-- | java/org/cef/handler/CefRenderHandler.java | 20 | ||||
-rw-r--r-- | java/org/cef/handler/CefRenderHandlerAdapter.java | 19 | ||||
-rw-r--r-- | java/org/cef/handler/CefRequestHandler.java | 17 | ||||
-rw-r--r-- | java/org/cef/handler/CefRequestHandlerAdapter.java | 6 | ||||
-rw-r--r-- | java/org/cef/handler/CefScreenInfo.java | 36 |
13 files changed, 448 insertions, 36 deletions
diff --git a/java/org/cef/CefClient.java b/java/org/cef/CefClient.java index 7aff09f..508390b 100644 --- a/java/org/cef/CefClient.java +++ b/java/org/cef/CefClient.java @@ -37,6 +37,7 @@ 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.misc.BoolRef; import org.cef.misc.StringRef; @@ -341,6 +342,24 @@ public class CefClient extends CefClientHandler return false; } + @Override + public boolean onCursorChange(CefBrowser browser, int cursorType) { + if (browser == null) { + return false; + } + + if (displayHandler_ != null && displayHandler_.onCursorChange(browser, cursorType)) { + return true; + } + + CefRenderHandler realHandler = browser.getRenderHandler(); + if (realHandler != null) { + return realHandler.onCursorChange(browser, cursorType); + } + + return false; + } + // CefDownloadHandler public CefClient addDownloadHandler(CefDownloadHandler handler) { @@ -718,14 +737,6 @@ public class CefClient extends CefClientHandler } @Override - public void onCursorChange(CefBrowser browser, int cursorType) { - if (browser == null) return; - - CefRenderHandler realHandler = browser.getRenderHandler(); - if (realHandler != null) realHandler.onCursorChange(browser, cursorType); - } - - @Override public boolean startDragging(CefBrowser browser, CefDragData dragData, int mask, int x, int y) { if (browser == null) return false; @@ -763,6 +774,15 @@ public class CefClient extends CefClientHandler } @Override + public boolean onOpenURLFromTab( + CefBrowser browser, CefFrame frame, String target_url, boolean user_gesture) { + if (isDisposed_) return true; + if (requestHandler_ != null && browser != null) + return requestHandler_.onOpenURLFromTab(browser, frame, target_url, user_gesture); + return false; + } + + @Override public CefResourceRequestHandler getResourceRequestHandler(CefBrowser browser, CefFrame frame, CefRequest request, boolean isNavigation, boolean isDownload, String requestInitiator, BoolRef disableDefaultHandling) { @@ -828,4 +848,9 @@ public class CefClient extends CefClientHandler if (realHandler != null) realHandler.onMouseEvent(browser, event, screenX, screenY, modifier, button); } + + @Override + public boolean getScreenInfo(CefBrowser arg0, CefScreenInfo arg1) { + return false; + } } diff --git a/java/org/cef/browser/CefBrowser.java b/java/org/cef/browser/CefBrowser.java index 83e5eae..35e4b32 100644 --- a/java/org/cef/browser/CefBrowser.java +++ b/java/org/cef/browser/CefBrowser.java @@ -19,7 +19,9 @@ import java.awt.Point; import java.awt.event.KeyEvent; import java.awt.event.MouseEvent; import java.awt.event.MouseWheelEvent; +import java.awt.image.BufferedImage; import java.util.Vector; +import java.util.concurrent.CompletableFuture; /** * Interface representing a browser. @@ -380,4 +382,27 @@ public interface CefBrowser { * @since api-1.2 */ void sendMouseWheelEvent(MouseWheelEvent e); + + /** + * Captures a screenshot-like image of the currently displayed content and returns it. + * <p> + * If executed on the AWT Event Thread, this returns an immediately resolved {@link + * java.util.concurrent.CompletableFuture}. If executed from another thread, the {@link + * java.util.concurrent.CompletableFuture} returned is resolved as soon as the screenshot + * has been taken (which must happen on the event thread). + * <p> + * The generated screenshot can either be returned as-is, containing all natively-rendered + * pixels, or it can be scaled to match the logical width and height of the window. + * This distinction is only relevant in case of differing logical and physical resolutions + * (for example with HiDPI/Retina displays, which have a scaling factor of for example 2 + * between the logical width of a window (ex. 400px) and the actual number of pixels in + * each row (ex. 800px with a scaling factor of 2)). + * + * @param nativeResolution whether to return an image at full native resolution (true) + * or a scaled-down version whose width and height are equal to the logical size + * of the screenshotted browser window + * @return the screenshot image + * @throws UnsupportedOperationException if not supported + */ + public CompletableFuture<BufferedImage> createScreenshot(boolean nativeResolution); } diff --git a/java/org/cef/browser/CefBrowserOsr.java b/java/org/cef/browser/CefBrowserOsr.java index 18a9d1e..c7acf60 100644 --- a/java/org/cef/browser/CefBrowserOsr.java +++ b/java/org/cef/browser/CefBrowserOsr.java @@ -6,21 +6,27 @@ package org.cef.browser; import com.jetbrains.cef.JCefAppConfig; 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.dnd.DropTarget; @@ -33,7 +39,22 @@ 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.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; @@ -47,8 +68,12 @@ 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. 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) { @@ -65,6 +90,7 @@ class CefBrowserOsr extends CefBrowser_N implements CefRenderHandler { @Override public void createImmediately() { + justCreated_ = true; // Create the browser immediately. createBrowserIfRequired(false); } @@ -104,11 +130,76 @@ class CefBrowserOsr extends CefBrowser_N implements CefRenderHandler { 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 @@ -119,7 +210,7 @@ class CefBrowserOsr extends CefBrowser_N implements CefRenderHandler { GLAutoDrawable glautodrawable, int x, int y, int width, int height) { browser_rect_.setBounds(canvas_.getBounds()/*x, y, width, height*/); // [tav] todo: revise it screenPoint_ = canvas_.getLocationOnScreen(); - wasResized(width, height); + wasResized(newWidth, newHeight); } @Override @@ -275,12 +366,15 @@ class CefBrowserOsr extends CefBrowser_N implements CefRenderHandler { } @Override - public void onCursorChange(CefBrowser browser, final int cursorType) { + 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; } @Override @@ -308,9 +402,182 @@ class CefBrowserOsr extends CefBrowser_N implements CefRenderHandler { createBrowser(getClient(), windowHandle, getUrl(), true, isTransparent_, null, getRequestContext()); } - } else { - // OSR windows cannot be reparented after creation. + } else if (hasParent && justCreated_) { + notifyAfterParentChanged(); setFocus(true); + justCreated_ = false; + } + } + + private void notifyAfterParentChanged() { + // With OSR there is no native window to reparent but we still need to send the + // notification. + getClient().onAfterParentChanged(this); + } + + @Override + public boolean getScreenInfo(CefBrowser browser, CefScreenInfo screenInfo) { + screenInfo.Set(scaleFactor_, depth, depth_per_component, false, browser_rect_.getBounds(), + browser_rect_.getBounds()); + + return true; + } + + @Override + public CompletableFuture<BufferedImage> createScreenshot(boolean nativeResolution) { + int width = (int) (canvas_.getWidth() * scaleFactor_); + int height = (int) (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<BufferedImage> pixelGrabberCallable = new Callable<BufferedImage>() { + @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<BufferedImage> future = new CompletableFuture<BufferedImage>(); + 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<BufferedImage> future = new CompletableFuture<BufferedImage>() { + 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; } } } diff --git a/java/org/cef/browser/CefBrowserWr.java b/java/org/cef/browser/CefBrowserWr.java index 0d63a83..4ef663b 100644 --- a/java/org/cef/browser/CefBrowserWr.java +++ b/java/org/cef/browser/CefBrowserWr.java @@ -20,7 +20,9 @@ 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; @@ -428,4 +430,9 @@ class CefBrowserWr extends CefBrowser_N { return false; } + + @Override + public CompletableFuture<BufferedImage> 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 d017bde..4571c40 100644 --- a/java/org/cef/browser/CefBrowser_N.java +++ b/java/org/cef/browser/CefBrowser_N.java @@ -153,7 +153,7 @@ abstract class CefBrowser_N extends CefNativeAdapter implements CefBrowser { boolean osr, boolean transparent, Component canvas, CefRequestContext context) { if (getNativeRef("CefBrowser") == 0 && !isPending_) { try { - /*isPending_ = */N_CreateBrowser( + N_CreateBrowser( clientHandler, windowHandle, url, osr, transparent, canvas, context); } catch (UnsatisfiedLinkError err) { err.printStackTrace(); diff --git a/java/org/cef/browser/CefRenderer.java b/java/org/cef/browser/CefRenderer.java index f5d8e7c..2a29546 100644 --- a/java/org/cef/browser/CefRenderer.java +++ b/java/org/cef/browser/CefRenderer.java @@ -30,6 +30,10 @@ class CefRenderer { return transparent_; } + protected int getTextureID() { + return texture_id_[0]; + } + @SuppressWarnings("static-access") protected void initialize(GL2 gl2) { if (initialized_context_ == gl2) return; diff --git a/java/org/cef/handler/CefDisplayHandler.java b/java/org/cef/handler/CefDisplayHandler.java index 0a14229..0affefc 100644 --- a/java/org/cef/handler/CefDisplayHandler.java +++ b/java/org/cef/handler/CefDisplayHandler.java @@ -4,9 +4,9 @@ package org.cef.handler; +import org.cef.CefSettings; import org.cef.browser.CefBrowser; import org.cef.browser.CefFrame; -import org.cef.CefSettings; /** * Implement this interface to handle events related to browser display state. @@ -14,7 +14,7 @@ import org.cef.CefSettings; */ public interface CefDisplayHandler { /** - * Handle address changes. + * Browser address changed. * @param browser The browser generating the event. * @param frame The frame generating the event. * @param url The new address. @@ -22,32 +22,29 @@ public interface CefDisplayHandler { public void onAddressChange(CefBrowser browser, CefFrame frame, String url); /** - * Handle title changes. + * Browser title changed. * @param browser The browser generating the event. * @param title The new title. */ public void onTitleChange(CefBrowser browser, String title); /** - * Called when the browser is about to display a tooltip. - * + * About to display a tooltip. * @param browser The browser generating the event. * @param text Contains the text that will be displayed in the tooltip. - * @return To handle the display of the tooltip yourself return true. + * @return true to handle the tooltip display yourself. */ public boolean onTooltip(CefBrowser browser, String text); /** - * Called when the browser receives a status message. - * + * Received a status message. * @param browser The browser generating the event. * @param value Contains the text that will be displayed in the status message. */ public void onStatusMessage(CefBrowser browser, String value); /** - * Called to display a console message. - * + * Display a console message. * @param browser The browser generating the event. * @param level * @param message @@ -57,4 +54,12 @@ public interface CefDisplayHandler { */ public boolean onConsoleMessage(CefBrowser browser, CefSettings.LogSeverity level, String message, String source, int line); + + /** + * Handle cursor changes. + * @param browser The browser generating the event. + * @param cursorType The new cursor type. + * @return true if the cursor change was handled. + */ + public boolean onCursorChange(CefBrowser browser, int cursorType); } diff --git a/java/org/cef/handler/CefDisplayHandlerAdapter.java b/java/org/cef/handler/CefDisplayHandlerAdapter.java index 88de539..80ab96b 100644 --- a/java/org/cef/handler/CefDisplayHandlerAdapter.java +++ b/java/org/cef/handler/CefDisplayHandlerAdapter.java @@ -4,9 +4,9 @@ package org.cef.handler; +import org.cef.CefSettings; import org.cef.browser.CefBrowser; import org.cef.browser.CefFrame; -import org.cef.CefSettings; /** * An abstract adapter class for receiving display events. @@ -39,4 +39,9 @@ public abstract class CefDisplayHandlerAdapter implements CefDisplayHandler { String message, String source, int line) { return false; } + + @Override + public boolean onCursorChange(CefBrowser browser, int cursorType) { + return false; + } } diff --git a/java/org/cef/handler/CefRenderHandler.java b/java/org/cef/handler/CefRenderHandler.java index f43822b..5637eb0 100644 --- a/java/org/cef/handler/CefRenderHandler.java +++ b/java/org/cef/handler/CefRenderHandler.java @@ -4,13 +4,13 @@ package org.cef.handler; +import org.cef.browser.CefBrowser; +import org.cef.callback.CefDragData; + import java.awt.Point; import java.awt.Rectangle; import java.nio.ByteBuffer; -import org.cef.browser.CefBrowser; -import org.cef.callback.CefDragData; - /** * Implement this interface to handle events when window rendering is disabled. * The methods of this class will be called on the UI thread. @@ -22,6 +22,15 @@ public interface CefRenderHandler { * @return The view rectangle. */ public Rectangle getViewRect(CefBrowser browser); + + /** + * Retrieve the screen info. + * @param browser The browser generating the event. + * @param screenInfo The screenInfo + * @return True if this callback was handled. False to fallback to defaults. + */ + public boolean getScreenInfo(CefBrowser browser, CefScreenInfo screenInfo); + /** * Retrieve the screen point for the specified view point. * @param browser The browser generating the event. @@ -64,9 +73,10 @@ public interface CefRenderHandler { /** * Handle cursor changes. * @param browser The browser generating the event. - * @param cursor The new cursor. + * @param cursorType The new cursor type. + * @return true if the cursor change was handled. */ - public void onCursorChange(CefBrowser browser, int cursor); + public boolean onCursorChange(CefBrowser browser, int cursorType); /** * Called when the user starts dragging content in the web view. Contextual diff --git a/java/org/cef/handler/CefRenderHandlerAdapter.java b/java/org/cef/handler/CefRenderHandlerAdapter.java index 88c9c32..ca1dba9 100644 --- a/java/org/cef/handler/CefRenderHandlerAdapter.java +++ b/java/org/cef/handler/CefRenderHandlerAdapter.java @@ -4,13 +4,13 @@ package org.cef.handler; +import org.cef.browser.CefBrowser; +import org.cef.callback.CefDragData; + import java.awt.Point; import java.awt.Rectangle; import java.nio.ByteBuffer; -import org.cef.browser.CefBrowser; -import org.cef.callback.CefDragData; - /** * An abstract adapter class for receiving render events. * The methods in this class are empty. @@ -18,13 +18,13 @@ import org.cef.callback.CefDragData; */ public abstract class CefRenderHandlerAdapter implements CefRenderHandler { @Override - public void onCursorChange(CefBrowser browser, int cursorIdentifer) { - return; + public Rectangle getViewRect(CefBrowser browser) { + return new Rectangle(0, 0, 0, 0); } @Override - public Rectangle getViewRect(CefBrowser browser) { - return new Rectangle(0, 0, 0, 0); + public boolean getScreenInfo(CefBrowser browser, CefScreenInfo screenInfo) { + return false; } @Override @@ -48,6 +48,11 @@ public abstract class CefRenderHandlerAdapter implements CefRenderHandler { ByteBuffer buffer, int width, int height) {} @Override + public boolean onCursorChange(CefBrowser browser, int cursorType) { + return false; + } + + @Override public boolean startDragging(CefBrowser browser, CefDragData dragData, int mask, int x, int y) { return false; } diff --git a/java/org/cef/handler/CefRequestHandler.java b/java/org/cef/handler/CefRequestHandler.java index a7917c6..3378981 100644 --- a/java/org/cef/handler/CefRequestHandler.java +++ b/java/org/cef/handler/CefRequestHandler.java @@ -48,6 +48,23 @@ public interface CefRequestHandler { boolean user_gesture, boolean is_redirect); /** + * Called on the UI thread before OnBeforeBrowse in certain limited cases + * where navigating a new or different browser might be desirable. This + * includes user-initiated navigation that might open in a special way (e.g. + * links clicked via middle-click or ctrl + left-click) and certain types of + * cross-origin navigation initiated from the renderer process (e.g. + * navigating the top-level frame to/from a file URL). + * + * @param browser The corresponding browser. + * @param frame The frame generating the event. Instance only valid within the scope of this + * method + * @param user_gesture True if the request was initiated by a user gesture. + * @return True to cancel navigation or false to continue + */ + boolean onOpenURLFromTab(CefBrowser browser, CefFrame frame, String target_url, + boolean user_gesture); + + /** * Called on the IO thread before a resource request is initiated. The |browser| and |frame| * values represent the source of the request. If this callback returns null the same method * will be called on the associated CefRequestContextHandler, if any. diff --git a/java/org/cef/handler/CefRequestHandlerAdapter.java b/java/org/cef/handler/CefRequestHandlerAdapter.java index baa8e6e..a5231d0 100644 --- a/java/org/cef/handler/CefRequestHandlerAdapter.java +++ b/java/org/cef/handler/CefRequestHandlerAdapter.java @@ -26,6 +26,12 @@ public abstract class CefRequestHandlerAdapter implements CefRequestHandler { } @Override + public boolean onOpenURLFromTab(CefBrowser browser, CefFrame frame, String target_url, + boolean user_gesture) { + return false; + } + + @Override public CefResourceRequestHandler getResourceRequestHandler(CefBrowser browser, CefFrame frame, CefRequest request, boolean isNavigation, boolean isDownload, String requestInitiator, BoolRef disableDefaultHandling) { diff --git a/java/org/cef/handler/CefScreenInfo.java b/java/org/cef/handler/CefScreenInfo.java new file mode 100644 index 0000000..8a8cd4a --- /dev/null +++ b/java/org/cef/handler/CefScreenInfo.java @@ -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. + +package org.cef.handler; + +import java.awt.Rectangle; + +/** + * + * @author shannah + */ +public class CefScreenInfo { + public double device_scale_factor; + public int depth; + public int depth_per_component; + public boolean is_monochrome; + public int x, y, width, height; + public int available_x, available_y, available_width, available_height; + + public void Set(double device_scale_factor, int depth, int depth_per_component, + boolean is_monochrome, Rectangle rect, Rectangle availableRect) { + this.device_scale_factor = device_scale_factor; + this.depth = depth; + this.depth_per_component = depth_per_component; + this.is_monochrome = is_monochrome; + this.x = rect.x; + this.y = rect.y; + this.width = rect.width; + this.height = rect.height; + this.available_x = availableRect.x; + this.available_y = availableRect.y; + this.available_width = availableRect.width; + this.available_height = availableRect.height; + } +} |