As we and many others are relying more and more on the Open Web Platform or HTML5 as more commonly referenced to. We want to bring some of that goodness to the our desktops too. With it we can utilize our current in house talent and existing code much more efficiently.
We decided to take shot at the new project called AppJS and try reimplementing Gnome’s good old menus with HTML5. Here we will take look on how AppJS delivered.
Originally we planned to use Python, Qt and Webkit to build it like we did with Iivari. But some research showed that the best tool for the job might be The Chromium Embedded Framework which allows developers to leverage all the hard work Google and the Chrome team has done on Webkit instead of just using for example the Webkit widget from Qt. Wikipedia has a pretty convincing list applications using it which lead us to the AppJS.
1 2 3 4 5 6 7 8 9 10 11 12
This would open up a chromeless browser window using a index.html from the content directory. This is just the beginning of course. Developers can communicate with browser code using DOM events.
Send event from node.js using
and receive it in the browser like any other DOM event with
1 2 3
It’s brilliant how it reuses APIs already known to HTML5 developers.
node.js require in the browser context!
Now this is where things get really exciting or confusing depending on how you look at it.
When using the current master branch (e2ef58b872) of AppJS it exposes
the node.js require function directly in the browser context. With the latest
release, currently 0.0.19, you can do that manually. This
means you can actually do
var fs = require("fs"); and
fs.readFile("./file.txt", ...); directly in the browser!
While this is quite impressive on a technology stand point I’m not too big fan of it. Why? Because this is very AppJS specific. The reason why HTML5 is so popular is because it runs just about everywhere. Writing apps with code like that won’t be able to run anywhere else but on AppJS. Using only the events for node.js api access would force developers to write operating system level code in abstract manner. Then it would be really easy to move the code to a real browser and just reimplement the event handlers.
I also have a more practical reason for not enjoying it too much. While this is
a really easy way to give module system to client-side code which it really
needs - it breaks others. We already use RequireJS for our client-side code and
it just does not work with AppJS if there is already a require function in the
global scope. Another practical issue is that some libraries which try detect
whether they are in the browser or in node.js get confused by this. Luckily the
AppJS developers are really responsive on the
#appjs channel on freenode and
they started looking for solutions to this after I mentioned this issue. For
now we solved this by forking AppJS and adding an option to
So back to reimplementing Gnome menus. The target for this first iteration was just to reimplement the existing features of the menu. Nothing too fancy. It reads menu content from a json file and builds a menu from it. In future we plan to integrate some communication channels from schools back to us at Opinsys and a remote update mechanism for the menu content so that we and our customers can update the menu content without rebuilding the LTSP Ubuntu images.
If you want try it feel free to grab a deb package from the Webmenu Github
repository’s downloads section. The package is bit hackish.
It installs Webmenu to
/opt/webmenu and adds couple executables to
The package contains all the dependencies which cannot be found from the
default Ubuntu repositories. That means it contains latest version of node.js,
AppJS and bunch of other random node.js modules. But hey it should be easy to
install at least.
Webmenu itself is licensed under GPLv2+.
It’s nice to be able to use existing HTML5 and node.js skills and libraries to build desktop apps. I hope that AppJS developers realize that this is the most compelling feature of AppJS and work out the quirks with the require and do not go too crazy with AppJS specific features. One good example of this is that developers can use some existing web frameworks from node.js with AppJS. I hope they keep working on this aspect too. I’d love to be able to use various connect middleware extensions for precompilers and such.