Closed rocksdanister closed 2 years ago
Looks like its possible to get rendered bitmap: http://cefsharp.github.io/api/71.0.0/html/M_CefSharp_Wpf_ChromiumWebBrowser_OnPaint.htm
http://cefsharp.github.io/api/57.0.0/html/P_CefSharp_OffScreen_ChromiumWebBrowser_Bitmap.htm
Looks like its possible to get rendered bitmap: http://cefsharp.github.io/api/71.0.0/html/M_CefSharp_Wpf_ChromiumWebBrowser_OnPaint.htm
http://cefsharp.github.io/api/57.0.0/html/P_CefSharp_OffScreen_ChromiumWebBrowser_Bitmap.htm
@rocksdanister Are you using the WinForms
or WPF
version of CefSharp
?
Winforms
Looks like its possible to get rendered bitmap: http://cefsharp.github.io/api/71.0.0/html/M_CefSharp_Wpf_ChromiumWebBrowser_OnPaint.htm
http://cefsharp.github.io/api/57.0.0/html/P_CefSharp_OffScreen_ChromiumWebBrowser_Bitmap.htm
This is only possible in the WPF/OffScreen
versions as each frame is rendered to a bitmap.
For the WinForms
version it is possible to take a screenshot
though this is often tricky.
Display static wallpaper when cef is paused.
Can you clarify what you mean by CEF paused
?
When fullscreen apps/games are run Lively will pause the wallpaper playback to reduce cpu/gpu usage.
LivelyCefsharp is a separate program (winform) from lively(wpf).
I pass the window handle to lively using:
GetBrowser().GetHost().GetWindowHandle()
then set it as child window of the new WorkerW window between the WorkerW instance that holds the Desktop Icons (SysListView32) and the Desktop Manager.
In order to let cef know to stop rendering the page lively will do this:
ShowWindow(cefhandle, SW_MINIMIZE);
Problem is this leaves a blank black area on screen which is not pleasant as wallpaper especially with additional options in lively settings such as pause wallpaper playback when apps are open, when on battery power etc.
I was wondering if something like WasHidden possible in window rendering, but display the last rendered frame as a static wallpaper.. like a play/pause button for cefsharp.
I understand this is a niche case; most of the wallpapers are gpu accelerated, so wpf version of cefsharp was not feasible.
Sorry for the late reply, WasHidden is only for WPF and OffScreen versions. Initially I didn't find anything particular helpful for the WinForms version. It's actually difficult to take a screenshot in WinForms, the only totally reliable option was to enable remote debugging and use DevTools protocol.
CEF recently added support for direct DevTools access, no need to enable remote debugging. So it's relatively trivial to take a screenshot starting from version 83.
I have been digging through the DevTools protocol documentation recently as there are lots of interesting new possibilities open to us.
https://chromedevtools.github.io/devtools-protocol/tot/Page/#method-setWebLifecycleState looks interesting, potentially you can put the browser into a frozen state. I have yet to try this so it's purely speculative at this point.
See https://github.com/cefsharp/CefSharp/issues/3158#issuecomment-651004911 for link to example of taking screenshot. This might be the best option.
I had a quick try with Page.setWebLifecylceState, this works:
id = await chromeBrowser.ExecuteDevToolsMethodAsync(0, "Page.setWebLifecycleState", new Dictionary<string, object> {{ "state", "frozen" }});
The usage drops and the view becomes background color (default: white.)
But when I try to unpause the paused page:
id = await chromeBrowser.ExecuteDevToolsMethodAsync(0, "Page.setWebLifecycleState", new Dictionary<string, object> {{ "state", "active" }});
it does not work, the id returned is non-zero.
This looks promising, adding the screenshot function ontop of this one should achieve what I'm looking for.
You could potentially just take a screenshot and load that into the browser, then navigate back when you wish to resume.
That would be unpleasant though, I tried about:blank
in the past.
Problem is process monitoring loop is checking every 500ms to see if any application is fullscreen so pause/unpause happen frequently, there will be loading delay(?) for the page and some users also use online webpages instead of offline version.
My other idea is to have two windows, one for the static picture and other for browser and when the browser window is minimized(paused) the static window is used to show the last captured screenshot...
I was hoping to avoid this complication if Page.setWebLifecylceState
worked.
That would be unpleasant though, I tried
about:blank
in the past.
No idea how about:blank
is related in this context? If you load the screenshot as a Data Uri
then it should be pretty quick as no network call needs to be made.
I was hoping to avoid this complication if
Page.setWebLifecylceState
worked.
You'd need to try it in an equivalent version of Chrome
to see what the expected behaviour is. Perhaps CEF
requires additional handling to support this.
Via DevTools
you can also pause/resume javascript execution. You can pause videos via javascript.
Just throwing some suggestions out there as I'm not familiar enough with your app to be specific.
No idea how about:blank is related in this context? If you load the screenshot as a Data Uri then it should be pretty quick as no network call needs to be made.
What I tried in the past is load about:blank
to pause execution and then navigate back to original page to unpause, problem was the loading back to original page took some time(especially if its online page) and this is very noticeable say when suddenly opening and closing windows explorer fullscreen and also this leads to webpage loses its saved state.
You'd need to try it in an equivalent version of Chrome to see what the expected behaviour is. Perhaps CEF requires additional handling to support this.
I tried with Chrome/85.0.4182.0 and the behavior looks the same, page is not unfreezing.
Via DevTools you can also pause/resume javascript execution. You can pause videos via javascript.
Not sure I understand, ~Debugger.pause? I tried and it worked but Debugger.resume does not work for some reason.~
Just throwing some suggestions out there as I'm not familiar enough with your app to be specific.
Help is appreciated.
WebView2 (Chromium) implementation of this is ready and in production.
@amaitland Calling DebugActiveProcess on "Intermediate D3D Window" CefSubProcess seems to do the trick.. working fine on my limited testing.
Thank you so much. Looks really good 👍🏻
Currently I'm minimizing the browser to let cef know to stop rendering, the side effect is the wallpaper region becomes black; there does not seem to be a function to stop rendering in non-headless cef as far as I can see.
Need to find a better solution, off the top of my head I can think of some ideas: