java/org/cef/browser/CefBrowser_N.java (969 lines of code) (raw):

// 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 org.cef.CefApp; import org.cef.CefBrowserSettings; import org.cef.CefClient; import org.cef.browser.CefDevToolsClient.DevToolsException; 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.handler.*; import org.cef.handler.CefDialogHandler.FileDialogMode; import org.cef.input.CefCompositionUnderline; import org.cef.input.CefTouchEvent; import org.cef.misc.CefLog; import org.cef.misc.CefPdfPrintSettings; import org.cef.misc.CefRange; 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.KeyEvent; import java.awt.event.MouseEvent; import java.awt.event.MouseWheelEvent; import java.awt.event.WindowEvent; import java.util.ArrayList; import java.util.List; import java.util.Vector; import java.util.concurrent.CompletableFuture; import javax.swing.SwingUtilities; /** * This class represents all methods which are connected to the * native counterpart CEF. * The visibility of this class is "package". To create a new * CefBrowser instance, please use CefBrowserFactory. */ abstract class CefBrowser_N extends CefNativeAdapter implements CefBrowser, CefAppStateHandler { private static final boolean TRACE_LIFESPAN = Boolean.getBoolean("jcef.trace.cefbrowser_n.lifespan"); private volatile boolean isPending_ = false; private final CefClient client_; private final String url_; private CefRequestContext request_context_; private volatile CefBrowser_N parent_ = null; private volatile Point inspectAt_ = null; private volatile CefDevToolsClient devToolsClient_ = null; private boolean closeAllowed_ = false; private volatile boolean isClosed_ = false; private volatile boolean isClosing_ = false; private volatile boolean isCreating_ = false; private final CefBrowserSettings settings_; private boolean isNativeCtxInitialized_ = false; private final List<Runnable> delayedActions_ = new ArrayList<>(); protected CefBrowser_N(CefClient client, String url, CefRequestContext context, 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(); CefApp.getInstance().onInitialization(this); } protected String getUrl() { return url_; } protected CefBrowser_N getParentBrowser() { return parent_; } protected Point getInspectAt() { return inspectAt_; } @Override public void stateHasChanged(CefApp.CefAppState state) { if (isClosing_ || isClosed_) return; if (CefApp.CefAppState.INITIALIZED == state) { synchronized (delayedActions_) { isNativeCtxInitialized_ = true; if (request_context_ == null) request_context_ = CefRequestContext.getGlobalContext(); delayedActions_.forEach(r -> r.run()); delayedActions_.clear(); } } } @Override public boolean isClosed() { return isClosed_; } @Override public boolean isClosing() { return isClosing_; } @Override public CefClient getClient() { return client_; } @Override public CefRequestContext getRequestContext() { return request_context_; } @Override public CefRenderHandler getRenderHandler() { return null; } @Override public CefWindowHandler getWindowHandler() { return null; } @Override public synchronized void setCloseAllowed() { closeAllowed_ = true; } @Override public synchronized boolean doClose() { if (closeAllowed_) { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { // Trigger close of the parent window. Component uiComponent = getUIComponent(); if (uiComponent == null) return; Component parent = SwingUtilities.getRoot(uiComponent); if (parent != null) { parent.dispatchEvent( new WindowEvent((Window) parent, WindowEvent.WINDOW_CLOSING)); } } }); // Allow the close to proceed. return false; } // Cancel the close. return true; } @Override public synchronized void onBeforeClose() { if (TRACE_LIFESPAN) CefLog.Debug("CefBrowser_N: %s: onBeforeClose", this); isClosed_ = true; if (request_context_ != null) request_context_.dispose(); if (parent_ != null) { parent_.closeDevTools(); parent_ = null; } if (devToolsClient_ != null) { devToolsClient_.close(); } } @Override public void openDevTools() { openDevTools(null); } @Override public synchronized void openDevTools(Point inspectAt) { createDevToolsBrowser(client_, url_, request_context_, this, inspectAt).createImmediately(); } protected abstract CefBrowser createDevToolsBrowser(CefClient client, String url, CefRequestContext context, CefBrowser parent, Point inspectAt); private void executeNative(Runnable nativeRunnable, String name) { synchronized (delayedActions_) { if (isNativeCtxInitialized_) { if (request_context_ == null) request_context_ = CefRequestContext.getGlobalContext(); nativeRunnable.run(); } else { CefLog.Debug("CefBrowser_N: %s: add delayed action %s", this, name); delayedActions_.add(nativeRunnable); } } } private void checkNativeCtxInitialized() { if (!isNativeCtxInitialized_) { String m1 = new Throwable().getStackTrace()[1].getMethodName(); CefLog.Error("CefBrowser_N: %s: can't invoke native method '%s' before native context initialized", this, m1); } } @Override public synchronized CefDevToolsClient getDevToolsClient() { if (!isPending_ || isClosing_ || isClosed_) { return null; } if (devToolsClient_ == null || devToolsClient_.isClosed()) { devToolsClient_ = new CefDevToolsClient(this); } return devToolsClient_; } CompletableFuture<Integer> executeDevToolsMethod(String method, String parametersAsJson) { CompletableFuture<Integer> future = new CompletableFuture<>(); executeNative(() -> { try { N_ExecuteDevToolsMethod(method, parametersAsJson, generatedMessageId -> { if (generatedMessageId <= 0) { future.completeExceptionally(new DevToolsException( String.format("Failed to execute DevTools method %s", method))); } else { future.complete(generatedMessageId); } }); } catch (UnsatisfiedLinkError error) { future.completeExceptionally(new DevToolsException( String.format("Failed to execute DevTools method %s", method), parametersAsJson, error)); } }, String.format("executeDevToolsMethod: %s(%s)", method, parametersAsJson)); return future; } CefRegistration addDevToolsMessageObserver(CefDevToolsMessageObserver observer) { return N_AddDevToolsMessageObserver(observer); } /** * Create a new browser. */ protected void createBrowser(CefClientHandler clientHandler, long windowHandle, String url, boolean osr, boolean transparent, Component canvas) { if (isClosing_ || isClosed_ || isCreating_) return; if (getNativeRef("CefBrowser") == 0 && !isPending_) { isCreating_ = true; executeNative(() -> { try { if (TRACE_LIFESPAN) CefLog.Debug("CefBrowser_N: %s: started native creation", this); N_CreateBrowser(clientHandler, windowHandle, url, osr, transparent, canvas, request_context_, settings_); } catch (UnsatisfiedLinkError err) { err.printStackTrace(); } }, "createBrowser"); } } /** * Called async from the (native) main UI thread. */ private void notifyBrowserCreated() { isPending_ = true; } /** * Create a new browser as dev tools */ protected final void createDevTools(CefBrowser_N parent, CefClientHandler clientHandler, long windowHandle, boolean osr, boolean transparent, Component canvas, Point inspectAt) { if (getNativeRef("CefBrowser") == 0 && !isPending_) { executeNative(() -> { try { isPending_ = N_CreateDevTools( parent, clientHandler, windowHandle, osr, transparent, canvas, inspectAt); } catch (UnsatisfiedLinkError err) { err.printStackTrace(); } }, "createDevTools"); } } /** * Returns the native window handle for the specified native surface handle. */ protected final long getWindowHandle(long surfaceHandle) { try { // NOTE: doesn't use cef ctx checkNativeCtxInitialized(); if (isNativeCtxInitialized_) return N_GetWindowHandle(surfaceHandle); } catch (UnsatisfiedLinkError err) { err.printStackTrace(); } return 0; } @Override protected void finalize() throws Throwable { close(true); super.finalize(); } // // NOTE: all native methods checks native CefBrowser pointer at first, // so they won't use native context before native CefBrowser created // @Override public boolean canGoBack() { try { checkNativeCtxInitialized(); if (isNativeCtxInitialized_) return N_CanGoBack(); } catch (UnsatisfiedLinkError ule) { ule.printStackTrace(); } return false; } @Override public void goBack() { try { checkNativeCtxInitialized(); if (isNativeCtxInitialized_) N_GoBack(); } catch (UnsatisfiedLinkError ule) { ule.printStackTrace(); } } @Override public boolean canGoForward() { try { checkNativeCtxInitialized(); if (isNativeCtxInitialized_) return N_CanGoForward(); } catch (UnsatisfiedLinkError ule) { ule.printStackTrace(); } return false; } @Override public void goForward() { try { checkNativeCtxInitialized(); if (isNativeCtxInitialized_) N_GoForward(); } catch (UnsatisfiedLinkError ule) { ule.printStackTrace(); } } @Override public boolean isLoading() { try { checkNativeCtxInitialized(); if (isNativeCtxInitialized_) return N_IsLoading(); } catch (UnsatisfiedLinkError ule) { ule.printStackTrace(); } return false; } @Override public void reload() { try { checkNativeCtxInitialized(); if (isNativeCtxInitialized_) N_Reload(); } catch (UnsatisfiedLinkError ule) { ule.printStackTrace(); } } @Override public void reloadIgnoreCache() { try { checkNativeCtxInitialized(); if (isNativeCtxInitialized_) N_ReloadIgnoreCache(); } catch (UnsatisfiedLinkError ule) { ule.printStackTrace(); } } @Override public void stopLoad() { try { checkNativeCtxInitialized(); if (isNativeCtxInitialized_) N_StopLoad(); } catch (UnsatisfiedLinkError ule) { ule.printStackTrace(); } } @Override public int getIdentifier() { try { checkNativeCtxInitialized(); if (isNativeCtxInitialized_) return N_GetIdentifier(); } catch (UnsatisfiedLinkError ule) { ule.printStackTrace(); } return -1; } @Override public CefFrame getMainFrame() { try { checkNativeCtxInitialized(); if (isNativeCtxInitialized_) return N_GetMainFrame(); } catch (UnsatisfiedLinkError ule) { ule.printStackTrace(); } return null; } @Override public CefFrame getFocusedFrame() { try { checkNativeCtxInitialized(); if (isNativeCtxInitialized_) return N_GetFocusedFrame(); } catch (UnsatisfiedLinkError ule) { ule.printStackTrace(); } return null; } @Override public CefFrame getFrameByIdentifier(String identifier) { try { checkNativeCtxInitialized(); if (isNativeCtxInitialized_) return N_GetFrame(identifier); } catch (UnsatisfiedLinkError ule) { ule.printStackTrace(); } return null; } @Override public CefFrame getFrameByName(String name) { try { checkNativeCtxInitialized(); if (isNativeCtxInitialized_) return N_GetFrame2(name); } catch (UnsatisfiedLinkError ule) { ule.printStackTrace(); } return null; } @Override public Vector<String> getFrameIdentifiers() { try { checkNativeCtxInitialized(); if (isNativeCtxInitialized_) return N_GetFrameIdentifiers(); } catch (UnsatisfiedLinkError ule) { ule.printStackTrace(); } return null; } @Override public Vector<String> getFrameNames() { try { checkNativeCtxInitialized(); if (isNativeCtxInitialized_) return N_GetFrameNames(); } catch (UnsatisfiedLinkError ule) { ule.printStackTrace(); } return null; } @Override public int getFrameCount() { try { checkNativeCtxInitialized(); if (isNativeCtxInitialized_) return N_GetFrameCount(); } catch (UnsatisfiedLinkError ule) { ule.printStackTrace(); } return -1; } @Override public boolean isPopup() { try { checkNativeCtxInitialized(); if (isNativeCtxInitialized_) return N_IsPopup(); } catch (UnsatisfiedLinkError ule) { ule.printStackTrace(); } return false; } @Override public boolean hasDocument() { try { checkNativeCtxInitialized(); if (isNativeCtxInitialized_) return N_HasDocument(); } catch (UnsatisfiedLinkError ule) { ule.printStackTrace(); } return false; } @Override public void viewSource() { try { checkNativeCtxInitialized(); if (isNativeCtxInitialized_) N_ViewSource(); } catch (UnsatisfiedLinkError ule) { ule.printStackTrace(); } } @Override public void getSource(CefStringVisitor visitor) { try { checkNativeCtxInitialized(); if (isNativeCtxInitialized_) N_GetSource(visitor); } catch (UnsatisfiedLinkError ule) { ule.printStackTrace(); } } @Override public void getText(CefStringVisitor visitor) { try { checkNativeCtxInitialized(); if (isNativeCtxInitialized_) N_GetText(visitor); } catch (UnsatisfiedLinkError ule) { ule.printStackTrace(); } } @Override public void loadRequest(CefRequest request) { try { checkNativeCtxInitialized(); if (isNativeCtxInitialized_) N_LoadRequest(request); } catch (UnsatisfiedLinkError ule) { ule.printStackTrace(); } } @Override public void loadURL(String url) { try { checkNativeCtxInitialized(); if (isNativeCtxInitialized_) N_LoadURL(url); } catch (UnsatisfiedLinkError ule) { ule.printStackTrace(); } } @Override public void executeJavaScript(String code, String url, int line) { try { checkNativeCtxInitialized(); if (isNativeCtxInitialized_) N_ExecuteJavaScript(code, url, line); } catch (UnsatisfiedLinkError ule) { ule.printStackTrace(); } } @Override public String getURL() { try { checkNativeCtxInitialized(); if (isNativeCtxInitialized_) return N_GetURL(); } catch (UnsatisfiedLinkError ule) { ule.printStackTrace(); } return ""; } @Override public void close(boolean force) { if (isClosing_ || isClosed_) return; if (force) isClosing_ = true; if (TRACE_LIFESPAN) CefLog.Debug("CefBrowser_N: %s: close, force=%d", this.toString(), force ? 1 : 0); synchronized (delayedActions_) { delayedActions_.clear(); } if (getNativeRef("CefBrowser") == 0) { CefLog.Debug("CefBrowser_N: %s: native part of browser wasn't created yet, browser will be closed immediately after creation", this); if (client_ != null) { client_.addLifeSpanHandler(new CefLifeSpanHandlerAdapter() { @Override public void onAfterCreated(CefBrowser browser) { if (browser == CefBrowser_N.this) { CefLog.Debug("CefBrowser_N: %s: close browser (immediately after creation)", browser); browser.close(force); } } }); } return; } try { checkNativeCtxInitialized(); if (isNativeCtxInitialized_) N_Close(force); } catch (UnsatisfiedLinkError ule) { ule.printStackTrace(); } } @Override public void setFocus(boolean enable) { try { checkNativeCtxInitialized(); if (isNativeCtxInitialized_) N_SetFocus(enable); } catch (UnsatisfiedLinkError ule) { ule.printStackTrace(); } } @Override public void setWindowVisibility(boolean visible) { try { checkNativeCtxInitialized(); if (isNativeCtxInitialized_) N_SetWindowVisibility(visible); } catch (UnsatisfiedLinkError ule) { ule.printStackTrace(); } } @Override public double getZoomLevel() { try { checkNativeCtxInitialized(); if (isNativeCtxInitialized_) return N_GetZoomLevel(); } catch (UnsatisfiedLinkError ule) { ule.printStackTrace(); } return 0.0; } @Override public void setZoomLevel(double zoomLevel) { try { checkNativeCtxInitialized(); if (isNativeCtxInitialized_) N_SetZoomLevel(zoomLevel); } catch (UnsatisfiedLinkError ule) { ule.printStackTrace(); } } @Override public void runFileDialog(FileDialogMode mode, String title, String defaultFilePath, Vector<String> acceptFilters, CefRunFileDialogCallback callback) { try { checkNativeCtxInitialized(); if (isNativeCtxInitialized_) N_RunFileDialog( mode, title, defaultFilePath, acceptFilters, callback); } catch (UnsatisfiedLinkError ule) { ule.printStackTrace(); } } @Override public void startDownload(String url) { try { checkNativeCtxInitialized(); if (isNativeCtxInitialized_) N_StartDownload(url); } catch (UnsatisfiedLinkError ule) { ule.printStackTrace(); } } @Override public void print() { try { checkNativeCtxInitialized(); if (isNativeCtxInitialized_) N_Print(); } catch (UnsatisfiedLinkError ule) { ule.printStackTrace(); } } @Override public void printToPDF( String path, CefPdfPrintSettings settings, CefPdfPrintCallback callback) { if (path == null || path.isEmpty()) { throw new IllegalArgumentException("path was null or empty"); } try { checkNativeCtxInitialized(); if (isNativeCtxInitialized_) N_PrintToPDF(path, settings, callback); } catch (UnsatisfiedLinkError ule) { ule.printStackTrace(); } } @Override public void find(String searchText, boolean forward, boolean matchCase, boolean findNext) { try { checkNativeCtxInitialized(); if (isNativeCtxInitialized_) N_Find(searchText, forward, matchCase, findNext); } catch (UnsatisfiedLinkError ule) { ule.printStackTrace(); } } @Override public void stopFinding(boolean clearSelection) { try { checkNativeCtxInitialized(); if (isNativeCtxInitialized_) N_StopFinding(clearSelection); } catch (UnsatisfiedLinkError ule) { ule.printStackTrace(); } } @Override public void closeDevTools() { try { checkNativeCtxInitialized(); if (isNativeCtxInitialized_) N_CloseDevTools(); } catch (UnsatisfiedLinkError ule) { ule.printStackTrace(); } } @Override public void replaceMisspelling(String word) { try { checkNativeCtxInitialized(); if (isNativeCtxInitialized_) N_ReplaceMisspelling(word); } catch (UnsatisfiedLinkError ule) { ule.printStackTrace(); } } /** * Notify that the browser was resized. * @param width The new width of the browser * @param height The new height of the browser */ @Override public final void wasResized(int width, int height) { try { checkNativeCtxInitialized(); if (isNativeCtxInitialized_) N_WasResized(width, height); } catch (UnsatisfiedLinkError ule) { ule.printStackTrace(); } } @Override public void notifyScreenInfoChanged() { try { checkNativeCtxInitialized(); if (isNativeCtxInitialized_) N_NotifyScreenInfoChanged(); } catch (UnsatisfiedLinkError ule) { ule.printStackTrace(); } } /** * Invalidate the UI. */ @Override public final void invalidate() { try { checkNativeCtxInitialized(); if (isNativeCtxInitialized_) N_Invalidate(); } catch (UnsatisfiedLinkError ule) { ule.printStackTrace(); } } /** * Send a key event. * @param e The event to send. */ @Override public final void sendKeyEvent(KeyEvent e) { try { checkNativeCtxInitialized(); if (isNativeCtxInitialized_) N_SendKeyEvent(e); } catch (UnsatisfiedLinkError ule) { ule.printStackTrace(); } } /** * Send a mouse event. * @param e The event to send. */ @Override public final void sendMouseEvent(MouseEvent e) { try { checkNativeCtxInitialized(); if (isNativeCtxInitialized_) N_SendMouseEvent(e); } catch (UnsatisfiedLinkError ule) { ule.printStackTrace(); } } /** * Send a mouse wheel event. * @param e The event to send. */ @Override public final void sendMouseWheelEvent(MouseWheelEvent e) { try { checkNativeCtxInitialized(); if (isNativeCtxInitialized_) N_SendMouseWheelEvent(e); } catch (UnsatisfiedLinkError ule) { ule.printStackTrace(); } } @Override public void sendTouchEvent(CefTouchEvent e) { try { N_SendTouchEvent(e); } catch (UnsatisfiedLinkError ule) { ule.printStackTrace(); } } /** * Call this method when the user drags the mouse into the web view (before * calling DragTargetDragOver/DragTargetLeave/DragTargetDrop). * |drag_data| should not contain file contents as this type of data is not * allowed to be dragged into the web view. File contents can be removed using * CefDragData::ResetFileContents (for example, if |drag_data| comes from * CefRenderHandler::StartDragging). * This method is only used when window rendering is disabled. */ protected final void dragTargetDragEnter( CefDragData dragData, Point pos, int modifiers, int allowedOps) { try { checkNativeCtxInitialized(); if (isNativeCtxInitialized_) N_DragTargetDragEnter(dragData, pos, modifiers, allowedOps); } catch (UnsatisfiedLinkError ule) { ule.printStackTrace(); } } /** * Call this method each time the mouse is moved across the web view during * a drag operation (after calling DragTargetDragEnter and before calling * DragTargetDragLeave/DragTargetDrop). * This method is only used when window rendering is disabled. */ protected final void dragTargetDragOver(Point pos, int modifiers, int allowedOps) { try { checkNativeCtxInitialized(); if (isNativeCtxInitialized_) N_DragTargetDragOver(pos, modifiers, allowedOps); } catch (UnsatisfiedLinkError ule) { ule.printStackTrace(); } } /** * Call this method when the user drags the mouse out of the web view (after * calling DragTargetDragEnter). * This method is only used when window rendering is disabled. */ protected final void dragTargetDragLeave() { try { checkNativeCtxInitialized(); if (isNativeCtxInitialized_) N_DragTargetDragLeave(); } catch (UnsatisfiedLinkError ule) { ule.printStackTrace(); } } /** * Call this method when the user completes the drag operation by dropping * the object onto the web view (after calling DragTargetDragEnter). * The object being dropped is |drag_data|, given as an argument to * the previous DragTargetDragEnter call. * This method is only used when window rendering is disabled. */ protected final void dragTargetDrop(Point pos, int modifiers) { try { checkNativeCtxInitialized(); if (isNativeCtxInitialized_) N_DragTargetDrop(pos, modifiers); } catch (UnsatisfiedLinkError ule) { ule.printStackTrace(); } } /** * Call this method when the drag operation started by a * CefRenderHandler.startDragging call has ended either in a drop or * by being cancelled. |x| and |y| are mouse coordinates relative to the * upper-left corner of the view. If the web view is both the drag source * and the drag target then all DragTarget* methods should be called before * DragSource* methods. * This method is only used when window rendering is disabled. */ protected final void dragSourceEndedAt(Point pos, int operation) { try { checkNativeCtxInitialized(); if (isNativeCtxInitialized_) N_DragSourceEndedAt(pos, operation); } catch (UnsatisfiedLinkError ule) { ule.printStackTrace(); } } /** * Call this method when the drag operation started by a * CefRenderHandler.startDragging call has completed. This method may be * called immediately without first calling DragSourceEndedAt to cancel a * drag operation. If the web view is both the drag source and the drag * target then all DragTarget* methods should be called before DragSource* * methods. * This method is only used when window rendering is disabled. */ protected final void dragSourceSystemDragEnded() { try { checkNativeCtxInitialized(); if (isNativeCtxInitialized_) N_DragSourceSystemDragEnded(); } catch (UnsatisfiedLinkError ule) { ule.printStackTrace(); } } protected final void updateUI(Rectangle contentRect, Rectangle browserRect) { try { checkNativeCtxInitialized(); if (isNativeCtxInitialized_) N_UpdateUI(contentRect, browserRect); } catch (UnsatisfiedLinkError ule) { ule.printStackTrace(); } } protected final void setParent(long windowHandle, Component canvas) { if (isClosing_ || isClosed_) return; try { checkNativeCtxInitialized(); if (isNativeCtxInitialized_) 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. */ protected final void notifyMoveOrResizeStarted() { try { checkNativeCtxInitialized(); if (isNativeCtxInitialized_) N_NotifyMoveOrResizeStarted(); } catch (UnsatisfiedLinkError ule) { ule.printStackTrace(); } } @Override public final void ImeSetComposition(String text, List<CefCompositionUnderline> underlines, CefRange replacementRange, CefRange selectionRange) { try { checkNativeCtxInitialized(); if (isNativeCtxInitialized_) N_ImeSetComposition(text, underlines, replacementRange, selectionRange); } catch (UnsatisfiedLinkError ule) { ule.printStackTrace(); } } @Override public final void ImeCommitText(String text, CefRange replacementRange, int relativeCursorPos) { try { checkNativeCtxInitialized(); if (isNativeCtxInitialized_) N_ImeCommitText(text, replacementRange, relativeCursorPos); } catch (UnsatisfiedLinkError ule) { ule.printStackTrace(); } } @Override public final void ImeFinishComposingText(boolean keepSelection) { try { checkNativeCtxInitialized(); if (isNativeCtxInitialized_) N_ImeFinishComposingText(keepSelection); } catch (UnsatisfiedLinkError ule) { ule.printStackTrace(); } } @Override public final void ImeCancelComposing() { try { checkNativeCtxInitialized(); if (isNativeCtxInitialized_) N_ImeCancelComposing(); } catch (UnsatisfiedLinkError ule) { ule.printStackTrace(); } } public void setWindowlessFrameRate(int frameRate) { try { checkNativeCtxInitialized(); if (isNativeCtxInitialized_) N_SetWindowlessFrameRate(frameRate); } catch (UnsatisfiedLinkError ule) { ule.printStackTrace(); } } public CompletableFuture<Integer> getWindowlessFrameRate() { final CompletableFuture<Integer> future = new CompletableFuture<>(); try { checkNativeCtxInitialized(); if (isNativeCtxInitialized_) { N_GetWindowlessFrameRate(future::complete); } else { future.completeExceptionally(new RuntimeException("The browser is not initialized yet")); } } catch (UnsatisfiedLinkError ule) { ule.printStackTrace(); future.completeExceptionally(ule); } 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, Component canvas, CefRequestContext context, CefBrowserSettings settings); private final native boolean N_CreateDevTools(CefBrowser parent, CefClientHandler clientHandler, long windowHandle, boolean osr, boolean transparent, Component canvas, 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(); private final native boolean N_CanGoForward(); private final native void N_GoForward(); private final native boolean N_IsLoading(); private final native void N_Reload(); private final native void N_ReloadIgnoreCache(); private final native void N_StopLoad(); private final native int N_GetIdentifier(); private final native CefFrame N_GetMainFrame(); private final native CefFrame N_GetFocusedFrame(); private final native CefFrame N_GetFrame(String identifier); private final native CefFrame N_GetFrame2(String name); private final native Vector<String> N_GetFrameIdentifiers(); private final native Vector<String> N_GetFrameNames(); private final native int N_GetFrameCount(); private final native boolean N_IsPopup(); private final native boolean N_HasDocument(); private final native void N_ViewSource(); private final native void N_GetSource(CefStringVisitor visitor); private final native void N_GetText(CefStringVisitor visitor); private final native void N_LoadRequest(CefRequest request); private final native void N_LoadURL(String url); private final native void N_ExecuteJavaScript(String code, String url, int line); private final native String N_GetURL(); private final native void N_Close(boolean force); private final native void N_SetFocus(boolean enable); private final native void N_SetWindowVisibility(boolean visible); private final native double N_GetZoomLevel(); private final native void N_SetZoomLevel(double zoomLevel); private final native void N_RunFileDialog(FileDialogMode mode, String title, String defaultFilePath, Vector<String> acceptFilters, CefRunFileDialogCallback callback); private final native void N_StartDownload(String url); private final native void N_Print(); private final native void N_PrintToPDF( String path, CefPdfPrintSettings settings, CefPdfPrintCallback callback); private final native void N_Find( String searchText, boolean forward, boolean matchCase, boolean findNext); private final native void N_StopFinding(boolean clearSelection); private final native void N_CloseDevTools(); 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_NotifyScreenInfoChanged(); private final native void N_SendKeyEvent(KeyEvent e); private final native void N_SendTouchEvent(CefTouchEvent e); private final native void N_SendMouseEvent(MouseEvent e); private final native void N_SendMouseWheelEvent(MouseWheelEvent 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); private final native void N_DragTargetDragLeave(); private final native void N_DragTargetDrop(Point pos, int modifiers); 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(); private final native void N_ImeSetComposition(String text, List<CefCompositionUnderline> underlines, CefRange replacementRange, CefRange selectionRange); private final native void N_ImeCommitText(String text, CefRange replacementRange, int relativeCursorPos); private final native void N_ImeFinishComposingText(boolean keepSelection); private final native void N_ImeCancelComposing(); private final native void N_SetWindowlessFrameRate(int frameRate); private final native void N_GetWindowlessFrameRate(IntCallback frameRateCallback); }