Is it possible to render web content over a clear background using WebKit? - webkit

I'm trying to gauge the possibility of a patch to WebKit which would allow all rendered graphics to be rendered onto a fully transparent background.
The desired effect is to render web content without any background at all, it should appear to float over the desktop (or whatever is displayed behind the browser window).
Has anyone seen an app do this? (I can think of some terminal emulators that can.) If anyone has worked inside of WebKit (or possibly Gecko?) do you think it would be possible to do this?
Update: I've come to realize that Mac OSX dashboard widgets use this exact technique. So, this must be possible.
Update 2: I've compiled WebKit on linux and noticed the configure options include:
--enable-dashboard-support
enable Dashboard support default=yes
I'm getting closer. Can anyone help?
Update 3: I continue to find references to this in posts on various related mailing lists.
https://lists.webkit.org/pipermail/webkit-dev/2008-September/005019.html
https://lists.webkit.org/pipermail/webkit-dev/2009-June/008182.html

Solved!
Through ongoing research, scouring forums and source code repositories, I peiced together the necessary steps to accomplish this using only libwebkit and a standard compiz desktop (any Xorg desktop with compositing should do).
For a current libwebkit (1.1.10-SVN), there is an Ubuntu PPA:
deb http://ppa.launchpad.net/webkit-team/ppa/ubuntu jaunty main
deb-src http://ppa.launchpad.net/webkit-team/ppa/ubuntu jaunty main
As far as the code goes, the key is calling webkit_web_view_set_transparent.
And of course the system you're running it on should have a capable graphics card (intel, radeon, or nvidia) and be running a compositing window manager (like Compiz).
And finally, to actually see transparency, the content you're viewing must set a transparent background using CSS3, otherwise it's still completely opaque.
It's as simple as:
BODY { background-color: rgba(0,0,0,0); }
Here' is the full sample for the simplest possible webkit browser app, with transparency support:
#include <gtk/gtk.h>
#include <webkit/webkit.h>
static void destroy_cb(GtkWidget* widget, gpointer data) {
gtk_main_quit();
}
int main(int argc, char* argv[]) {
gtk_init(&argc, &argv);
if(!g_thread_supported())
g_thread_init(NULL);
// Create a Window, set colormap to RGBA
GtkWidget* window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
GdkScreen *screen = gtk_widget_get_screen(window);
GdkColormap *rgba = gdk_screen_get_rgba_colormap (screen);
if (rgba && gdk_screen_is_composited (screen)) {
gtk_widget_set_default_colormap(rgba);
gtk_widget_set_colormap(GTK_WIDGET(window), rgba);
}
gtk_window_set_default_size(GTK_WINDOW(window), 800, 800);
g_signal_connect(window, "destroy", G_CALLBACK(destroy_cb), NULL);
// Optional: for dashboard style borderless windows
gtk_window_set_decorated(GTK_WINDOW(window), FALSE);
// Create a WebView, set it transparent, add it to the window
WebKitWebView* web_view = web_view = WEBKIT_WEB_VIEW(webkit_web_view_new());
webkit_web_view_set_transparent(web_view, TRUE);
gtk_container_add (GTK_CONTAINER(window), GTK_WIDGET(web_view));
// Load a default page
webkit_web_view_load_uri(web_view, "http://stackoverflow.com/");
// Show it and continue running until the window closes
gtk_widget_grab_focus(GTK_WIDGET(web_view));
gtk_widget_show_all(window);
gtk_main();
return 0;
}

Back in Safari 1.3 and 2, there was a hidden debug menu (invoked via the Terminal: defaults write com.apple.Safari IncludeDebugMenu 1) that included a “Use Transparent Window” option.
http://www.macosxhints.com/article.php?story=20050418015445258
http://www.wiredatom.com/blog/2005/10/20/safari-transparency/
Not sure if this was a WebKit thing or a Safari thing though.
(In Safari 3, the debug menu seems to have been replaced by the “Develop” menu (enable in Preferences > Advanced) which doesn’t have the transparent window option.)

Basically you want to be setting the ARGB colour space to be sending to the window manager. Obviously only window managers that support compositing will be able to take advantage of this.
You might want to talk to the screenlet and compiz developers they should be able to help out more.

This gist works for me, as of 2013, tested only with ubuntu:
https://gist.github.com/pouria-mellati/7771779

I have a new solution which is really easy to do, for a single screenshot. It's using node.js with phantom.js library.
install node.js
run 'npm install -g phantomjs' in console/terminal
save the following as script.js and run it from console 'phantomjs script.js'
var page = require('webpage').create();
page.viewportSize = { width: 1920, height: 1500 };
page.open("http://www.theWebYouWantToRender");
page.onLoadFinished = function(status) {
page.evaluate(function() {
document.body.style.background = 'transparent';
});
page.render('render.png');
phantom.exit();
};
profit? :) enjoy

Related

Is it possible to make chromium instantly reload on tab crash?

We are running chromium 83 on an embedded system and experience some random tab crashes.
Is it possible to directly reload a tab in chromium, if it crashes (without showing the "Aw snap!" page)?
We're currently trying to patch the source code to get it working and those were our approaches so far.
(both in sad_tab_helper.cc -> SadTabHelper::RenderProcessGone()
Approach 1:
if (SadTab::ShouldShow(status)) {
web_contents()->GetController().Reload(content::ReloadType::NORMAL, true);
}
Approach 2:
if (SadTab::ShouldShow(status)) {
content::RunOrPostTaskOnThread(
FROM_HERE,
content::BrowserThread::ID::UI,
base::BindOnce(
[](content::WebContents* contents) {
contents->GetController().Reload(content::ReloadType::NORMAL, true);
},
std::move(web_contents())));
}
Both changes finally lead to crash of the entire browser.
It seems that chromium tries to reload the page but as said, it then crashes. The log we get are:
[1663:1671:0321/090914.211931:VERBOSE1:network_delegate.cc(32)] NetworkDelegate::NotifyBeforeURLRequest: http://127.0.0.1/login
[1663:1671:0321/090919.082378:ERROR:broker_posix.cc(40)] Recvmsg error: Connection reset by peer (104)
After that the entire browser crashes. Is there a way to do what we want or are we on a dead end here?
The second approach is suboptimal, SadTabHelper::RenderProcessGone only runs on UI.
Initiating navigation while handling notifications from any WebContentsObserver (SadTabHelper is a WebContentsObserver) must be avoided. It leads to problems. The both approaches attempt to do this. I suppose using base::PostTask instead of content::RunOrPostTaskOnThread should help.
if (SadTab::ShouldShow(status)) {
base::PostTask(
FROM_HERE,
{content::BrowserThread::UI},
base::BindOnce(
[](content::WebContents* contents) {
contents->GetController().Reload(content::ReloadType::NORMAL, true);
},
web_contents()));
}
My reputation is not good enough to comment so I can't leave this comment where it should be.
If you come across this particular solution, the required includes are:
#include "base/task_scheduler/post_task.h"
#include "content/public/browser/browser_thread.h"
#include "base/bind.h"

Scene rendering goes dark after calling LoadScene/LoadLevel [duplicate]

I completed Unity's roll-a-ball tutorial and it works fine. I changed a couple of materials to make it look better. I also added a C# script that should restart the level when the player falls off of the ground (I disables the walls). I am using Unity 5.5.
It initially looks like this:
But when I go off the edge and the level restarts, it looks like this:
It sometimes looks like this for a few seconds after opening unity when the editor is loading.
Here is the script:
using UnityEngine;
using System.Collections;
public class DeathTrigger : MonoBehaviour {
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
}
void OnTriggerEnter (Collider other)
{
if (other.gameObject.CompareTag("Player"))
Application.LoadLevel(Application.loadedLevel);
}
}
Any ideas on what's causing this?
The colors and materials are loaded. This is a lighting problem because lighliting is still calculating in the background. This will likely occur in the Editor only. This should not happen in the build.
Depending on your Unity version, you can fix this by going to Windows --> Lighting --> Settings then go to the Scene tab. Scroll down and disable Auto Generate checkbox then click the Generate Lightning button.
For older version of Unity with no Auto Generate checkbox, see here.
After play with Lighting tools, only one thing should be change on Lighting Setting for every scene.
Window > Rendering > Lighting (Unity 2020)
Click at Environment Tab
At Environment Lighting, change Source from Skybox to Color.
Select white color from Ambient Color.
Done. Try test it.
Before
After
I found many solutions online but I was missing out a step, so I hope this helps.
Most solutions indicated to go to Windows->Lightning, then untick Auto and Click Generate Lighting. My problem was that while I was pressing the generate button I did not have all of my scenes loaded for preview (at least not the scene I had problems with), so it was only applying light generation to the loaded scenes. Make sure all scenes are loaded when generating the lights.
Try Clearing Baked Data if you are using unity version around 5.5
Go to Windows->Lightning->Untick Auto->Now Click dropdown arrow of Build Button which is near Auto(Check Box) -> Select Clear Baked Data.
Now try Your code which looks fine although SceneManager.LoadScene (1); is enough.
Also unloading the previous scene and setting new scene as active scene is a good practice.
This worked for me.
File > Build settings > player Settings > (on the left) Graphics > (Top-Right) gear icon > Reset
I'm a newbie and none of the advice on web helped me. However when I went to Window > Rendering > Lightning > scene tab; If "lightning setting" says “none”, click on it and choose “demo”- setting. Press “generate”.
So it seems like it was missing settings all together which made the scene go dark when loaded.
I encountered the exact same problem. What worked for me was to set Directional Light > Light > Mode to Realtime. (it was Baked, for some reason)
I hope this can help someone in the future.

Node-Webkit - Starting Maximized

I don't want a fullscreen application, but I would like to start a Node-Webkit application maximized. Can this be done? I am guessing its something to do with package.json, but can't seem to find what needs to be done.
I don't think the manifest has an option to do that. Instead, call nw's Window.maximize() on startup. Something like:
// Load native UI library
var ngui = require('nw.gui');
// Get the current window
var nwin = ngui.Window.get();
Sometime later, in onload or some other point where you're ready to show the window:
onload = function() {
nwin.show();
nwin.maximize();
}
This is described in the node-webkit wiki. I don't think you can call maximize before showing the main window though (if it's hidden in manifest), but I haven't really dug into it.
You may want to consider saving the window position, from a UX standpoint. The wiki has an example for doing this.

Video.js controls come back on pause even though disabled

The subject pretty much says it all. I have a Video.js instance with controls turned off (aka no "controls" in the markup). It works brilliantly, but when I pause the video (using my external custom button and myPlayer.pause() the controls on the video fade back in. When I hit play, they fade out again.
This definitely doesn't seem like the way it should work. Does anyone know if this is a bug, or I'm just missing something?
ctangney's answer only works when using the uncompressed (dev) version of videojs, since once compressed the lockShowing method is renamed (so is player() for that matter). Hopefully his merge request for issue 556 will be accepted soon.
When lockShowing is called on pause() it adds the class vjs-lock-showing to the controls element, which has the css: display: block !important. This is causing the inline style of display:none, added by the disable() method, to be trumped. Here is work around which addresses the CSS specificity problem, and works with the compressed and uncompressed videojs:
var v = videojs("video", {});
if(!v.controls()) {
v.controlBar.el().className = v.controlBar.el().className + ' vjs-controls-disabled';
}
Then add to the bottom of the css file(s):
.vjs-controls-disabled {display: none !important;}
(Or you could just remove the !important from .vjs-lock-showing)
This is a confirmed bug. I see a proposed fix there, but it's still an open pull request at the moment. In the meantime you can fix this by just overwriting the ControlBar's lockShowing method.
var vid = videojs("video", {});
if (!vid.player().controls()) {
vid.controlBar.lockShowing = function(){};
}
... since (currently) the controlbar attaches a listener to 'pause' events and calls lockShowing().

App works as desired in debug mode but crashes in Rally environment

I have created an app that creates a grid dynamically, as well as lets the user make changes to one of the grid columns via a 'numberfield' editor. Everything is working great in the debug environment but when I try to edit one of the fields in the Rally environment it crashes the app. From the looks of it, the iframe containing the app is just reloading altogether.
Now, here's the weird part that may be a clue to what's going on. The app crashes after I click elsewhere on the app (committing the change) but if I scroll the mouse wheel somewhere on the app, the spinner loses focus (no up/down arrows) and then if I click somewhere the edits are applied and the app doesn't crash. Once again in the debug mode I don't need to go through this, I can just click elsewhere and the changes are applied.
This is a known issue with 2.0p5 that will be fixed with the next release of the SDK. Basically it's using a sledgehammer to respond to the fact that something was edited and refreshing it. Since the new SDK can communicate with the message bus this is totally unnecessary...
In the meantime you should be able to patch your app by defining a global Rally.getApp function that returns your app instance to prevent the hard refresh:
//In your app definition give it an xtype:
Ext.define('My.App', {
extend: 'Rally.app.App',
//...
alias: 'widget.myapp'
//...
});
//Find the app instance by its xtype and return it
Rally.getApp = function() {
return Ext.ComponentQuery.query('myapp')[0];
};
You can then delete that code once 2.0p6 is released and you upgrade.