Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use CEF Browser on Desktop #7

Merged
merged 11 commits into from
Sep 24, 2023
Merged

Use CEF Browser on Desktop #7

merged 11 commits into from
Sep 24, 2023

Conversation

DatL4g
Copy link
Collaborator

@DatL4g DatL4g commented Sep 21, 2023

This PR get's rid of the JavaFX Browser (and all it's problems).

It comes with a breaking change for desktop, as it needs at least an install dir.
This can (should) be called in the app init process, not sure how we document this in the README.

It needs to be called once (on app start), it can be called multiple times (executes once only).

LaunchedEffect(Unit) {
	Cef.init(builder = {
		installDir = File("jcef-bundle")
	})
}

Adding the Composable remains the same

@KevinnZou
Copy link
Owner

Awesome! I will review it soon and merge the PR if nothing goes wrong. Thanks again!

Copy link
Owner

@KevinnZou KevinnZou left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking great! Thanks for this, just one minor thing is the implementation of evaluateJavaScript. Since I already released a new version that supports JavaScript evaluation, the CEF browser also has to support it and then be able to merge it into the main branch. Is it because implementing evaluateJavaScript in CEF is more complicated than JavaFX so you left it as a todo?

removed test method
@KevinnZou
Copy link
Owner

I really appreciate your documentation!

@DatL4g
Copy link
Collaborator Author

DatL4g commented Sep 22, 2023

I added the execution method without calling the callback.

If you want you can pin me as maintainer, since you're not that familiar with CEF (or desktop development in general) I'm willing to maintain that part.

@KevinnZou
Copy link
Owner

I added the execution method without calling the callback.

If you want you can pin me as maintainer, since you're not that familiar with CEF (or desktop development in general) I'm willing to maintain that part.

Great! I have invited you!

@KevinnZou
Copy link
Owner

Hello, I just ran your code locally and encountered the following issue. Is there any configuration that needs to be done? I have already run the initialization code once to download the CEF module, but when I ran it for the second time, I encountered this problem.

Stacktrace

9月 22, 2023 9:55:09 下午 me.friwi.jcefmaven.impl.progress.ConsoleProgressHandler handleProgress
信息: LOCATING |> In progress...
9月 22, 2023 9:55:10 下午 me.friwi.jcefmaven.impl.progress.ConsoleProgressHandler handleProgress
信息: INITIALIZING |> In progress...
9月 22, 2023 9:55:10 下午 me.friwi.jcefmaven.impl.progress.ConsoleProgressHandler handleProgress
信息: INITIALIZED |> In progress...
initialize on Thread[AWT-EventQueue-0,6,main] with library path /Users/KMM/compose-webview-multiplatform/desktopApp/jcef-bundle
[0922/215510.659231:ERROR:iopm_power_source_sampling_event_source.cc(31)] IOPMPowerSource service not found
Exception in thread "AWT-EventQueue-0" java.lang.IllegalAccessError: class org.cef.browser.mac.CefBrowserWindowMac (in unnamed module @0x447a70b2) cannot access class sun.awt.AWTAccessor (in module java.desktop) because module java.desktop does not export sun.awt to unnamed module @0x447a70b2
	at org.cef.browser.mac.CefBrowserWindowMac.getWindowHandle(CefBrowserWindowMac.java:27)
	at org.cef.browser.CefBrowserWr.getWindowHandle(CefBrowserWr.java:337)
	at org.cef.browser.CefBrowserWr.access$600(CefBrowserWr.java:49)
	at org.cef.browser.CefBrowserWr$3.addNotify(CefBrowserWr.java:232)
	at java.desktop/java.awt.Container.addNotify(Unknown Source)
	at java.desktop/javax.swing.JComponent.addNotify(Unknown Source)
	at java.desktop/java.awt.Container.addImpl(Unknown Source)
	at java.desktop/javax.swing.JLayeredPane.addImpl(Unknown Source)
	at java.desktop/java.awt.Container.add(Unknown Source)
	at androidx.compose.ui.awt.ComposeWindowDelegate$_pane$1.add(ComposeWindowDelegate.desktop.kt:74)
	at androidx.compose.ui.awt.SwingPanel_desktopKt$SwingPanel$3.invoke(SwingPanel.desktop.kt:139)
	at androidx.compose.ui.awt.SwingPanel_desktopKt$SwingPanel$3.invoke(SwingPanel.desktop.kt:100)
	at androidx.compose.runtime.DisposableEffectImpl.onRemembered(Effects.kt:81)
	at androidx.compose.runtime.CompositionImpl$RememberEventDispatcher.dispatchRememberObservers(Composition.kt:1137)
	at androidx.compose.runtime.CompositionImpl.applyChangesInLocked(Composition.kt:828)
	at androidx.compose.runtime.CompositionImpl.applyChanges(Composition.kt:849)
	at androidx.compose.runtime.Recomposer$runRecomposeAndApplyChanges$2$1.invoke(Recomposer.kt:625)
	at androidx.compose.runtime.Recomposer$runRecomposeAndApplyChanges$2$1.invoke(Recomposer.kt:537)
	at androidx.compose.runtime.BroadcastFrameClock$FrameAwaiter.resume(BroadcastFrameClock.kt:42)
	at androidx.compose.runtime.BroadcastFrameClock.sendFrame(BroadcastFrameClock.kt:71)
	at androidx.compose.ui.ComposeScene.render(ComposeScene.skiko.kt:456)
	at androidx.compose.ui.awt.ComposeBridge$skikoView$1$onRender$1.invoke(ComposeBridge.desktop.kt:153)
	at androidx.compose.ui.awt.ComposeBridge$skikoView$1$onRender$1.invoke(ComposeBridge.desktop.kt:152)
	at androidx.compose.ui.awt.ComposeBridge.catchExceptions(ComposeBridge.desktop.kt:126)
	at androidx.compose.ui.awt.ComposeBridge.access$catchExceptions(ComposeBridge.desktop.kt:59)
	at androidx.compose.ui.awt.ComposeBridge$skikoView$1.onRender(ComposeBridge.desktop.kt:152)
	at org.jetbrains.skiko.SkiaLayer.update$skiko(SkiaLayer.awt.kt:548)
	at org.jetbrains.skiko.redrawer.AWTRedrawer.update(AWTRedrawer.kt:54)
	at org.jetbrains.skiko.redrawer.MetalRedrawer$frameDispatcher$1.invokeSuspend(MetalRedrawer.kt:83)
	at org.jetbrains.skiko.redrawer.MetalRedrawer$frameDispatcher$1.invoke(MetalRedrawer.kt)
	at org.jetbrains.skiko.redrawer.MetalRedrawer$frameDispatcher$1.invoke(MetalRedrawer.kt)
	at org.jetbrains.skiko.FrameDispatcher$job$1.invokeSuspend(FrameDispatcher.kt:33)
	at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
	at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:108)
	at java.desktop/java.awt.event.InvocationEvent.dispatch(Unknown Source)
	at java.desktop/java.awt.EventQueue.dispatchEventImpl(Unknown Source)
	at java.desktop/java.awt.EventQueue$3.run(Unknown Source)
	at java.desktop/java.awt.EventQueue$3.run(Unknown Source)
	at java.base/java.security.AccessController.doPrivileged(Unknown Source)
	at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
	at java.desktop/java.awt.EventQueue.dispatchEvent(Unknown Source)
	at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
	at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
	at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
	at java.desktop/java.awt.EventDispatchThread.pumpEvents(Unknown Source)
	at java.desktop/java.awt.EventDispatchThread.pumpEvents(Unknown Source)
	at java.desktop/java.awt.EventDispatchThread.run(Unknown Source)
	Suppressed: kotlinx.coroutines.internal.DiagnosticCoroutineContextException: [androidx.compose.ui.awt.ComposeBridge$coroutineExceptionHandler$1@2262b04b, androidx.compose.runtime.BroadcastFrameClock@6f791fc, StandaloneCoroutine{Cancelling}@23472b07, FlushCoroutineDispatcher@1de9eaa]
objc[66825]: Class WebSwapCGLLayer is implemented in both /System/Library/Frameworks/WebKit.framework/Versions/A/Frameworks/WebCore.framework/Versions/A/Frameworks/libANGLE-shared.dylib (0x7ffb56c75378) and /Users/kevinnzou/NetEase/KMM/compose-webview-multiplatform/desktopApp/jcef-bundle/Chromium Embedded Framework.framework/Libraries/libGLESv2.dylib (0x109d00220). One of the two will be used. Which one is undefined.

@DatL4g
Copy link
Collaborator Author

DatL4g commented Sep 22, 2023

MacOS and AWT is always a bit tricky.

If you want to just run it, add this JVM Flags:

--add-opens java.desktop/sun.awt=ALL-UNNAMED
--add-opens java.desktop/sun.lwawt=ALL-UNNAMED
--add-opens java.desktop/sun.lwawt.macosx=ALL-UNNAMED

If you package it add this in the build.gradle.kts:

compose {
	desktop {
		...
		nativeDistributions {
			...
			includeAllModules = true
		}
	}
}

@KevinnZou
Copy link
Owner

MacOS and AWT is always a bit tricky.

If you want to just run it, add this JVM Flags:

--add-opens java.desktop/sun.awt=ALL-UNNAMED
--add-opens java.desktop/sun.lwawt=ALL-UNNAMED
--add-opens java.desktop/sun.lwawt.macosx=ALL-UNNAMED

If you package it add this in the build.gradle.kts:

compose {
	desktop {
		...
		nativeDistributions {
			...
			includeAllModules = true
		}
	}
}

Thank you for your help! The basic sample is currently functioning properly. However, I am experiencing issues when attempting to test the LoadHtml Sample, as it only displays a blank screen. Can you confirm whether it is functioning correctly on your end?

By the way, there is another error. It will not crash the app but will be logged each time it runs.

[0923/095304.768528:ERROR:iopm_power_source_sampling_event_source.cc(31)] IOPMPowerSource service not found
objc[93200]: Class WebSwapCGLLayer is implemented in both /System/Library/Frameworks/WebKit.framework/Versions/A/Frameworks/WebCore.framework/Versions/A/Frameworks/libANGLE-shared.dylib (0x7ffb56c75378) and /Users/KMM/compose-webview-multiplatform/desktopApp/jcef-bundle/Chromium Embedded Framework.framework/Libraries/libGLESv2.dylib (0x10afcd220). One of the two will be used. Which one is undefined.

@DatL4g
Copy link
Collaborator Author

DatL4g commented Sep 24, 2023

Fixed loading and seemed like the html style was somewhat incorrect.

@KevinnZou
Copy link
Owner

Fixed loading and seemed like the html style was somewhat incorrect.

Yes, it appears to be related to the color value format. I have resolved the issue and made the necessary updates to the ReadMe. I believe it is now ready for merging. Is there anything else you would like to include? If not, I intend to merge the pull request and proceed with the release of the new version.

@DatL4g
Copy link
Collaborator Author

DatL4g commented Sep 24, 2023

I'm ready for merging.

I'll (try) work on new and improved features, as Jetbrains CEF is even better and could solve problems like the css thing and evaluateJavascript but I have to get in touch with the Jetbrains Team first.

@KevinnZou
Copy link
Owner

I'm ready for merging.

I'll (try) work on new and improved features, as Jetbrains CEF is even better and could solve problems like the css thing and evaluateJavascript but I have to get in touch with the Jetbrains Team first.

Cool! I will merge it soon.

For JetBrains CEF, I also saw many developers recommend it when I was researching JCEF. Feel free to do it if you think it is a better option. Thank you for your contribution!

@KevinnZou KevinnZou merged commit 8552706 into KevinnZou:main Sep 24, 2023
@KevinnZou KevinnZou linked an issue Sep 25, 2023 that may be closed by this pull request
@KevinnZou KevinnZou self-assigned this Oct 20, 2023
@KevinnZou KevinnZou added the enhancement New feature or request label Oct 20, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Access the Android WebView Settings
2 participants