I wrote a simple makefile which clones the required modules as git submodules and builds them. It works like this
git clone git://github.com/marcopg/sugar-build.git
make bootstrap
make build
make run
It’s pretty quick because it only builds the sugar modules and pygobject (the current version in fedora is not new enough, I’ll drop that as soon as it’s fixed).
This is not yet how I would like sugar to be built, but I hope it’s a step in the right direction.
I run across a very interesting project which should make the whole GNOME platform accessible from node.js. That’s something I was dreaming of when I experimented with HTML activities. Maybe I should pick that experiment up again some time…
I wanted to build the sugar shell on F15. I tried sugar-jhbuild and it didn’t work out of the box, so I thought I’d just do it manually. It was pretty painful, I’m sharing it in case someone tries to do the same.
First I installed a few dependencies. I was starting from a clean Fedora 15 livecd install.
sudo yum install gcc intltool libtool glib2-devel python-devel \
pygobject2-devel pygtk2-devel alsa-lib-devel libSM-devel \
gnome-common icon-naming-utils xcursorgen GConf2-devel \
hippo-canvas-python python-cjson python-dateutil \
pygtksourceview gnome-python2-rsvg vte
Then I checked out from git.sugarlabs.org the following modules:
sugar-base
sugar-toolkit
sugar-artwork
sugar-datastore
sugar-shell
I built each of them in that order with
./autogen.sh --prefix=~/Development/sugar/build
make
make install
I manually installed the schemas in the system prefix, I’m not sure if there is a better solution these days, even with jhbuild.
sudo GCONF_CONFIG_SOURCE=xml:merged:/etc/gconf/gconf.xml.defaults \
gconftool-2 --makefile-install-rule \
~/Development/sugar/sugar-shell/data/sugar.schemas
I created a script exporting various environment variables and sourced it
export PATH=~/Development/sugar/build/bin:$PATH
export PYTHONPATH=~/Development/sugar/build/lib/python2.7/site-packages
export XDG_DATA_DIRS=~/Development/sugar/build/share
export GTK_PATH=~/Development/sugar/build/lib/gtk-2.0
export GTK_DATA_PREFIX=~/Development/sugar/build
Running sugar-emulator in GNOME was crashing with weird errors for some reason, but it works from a basic X session with just a gnome-terminal in it.
One of the limitations with the current Sugar architecture is that GTK isn’t really a good toolkit to be creative with. I would like to write activities in HTML but still be able to access services like the icon theme, the datastore and the presence service. When I wrote hulahop I had this also in mind.
Years passed and I think we might now have the blocks to build something better. So I made a little experiment. I wrote a toy text editor. A really simple one, it can only save to a single file. But I hope it shows a possible way to tackle the issue. Anyway, code first (but not so much of it, don’t hold your breath)!
The engine, a web server, based on nodejs. It’s using http but I’d have probably used web sockets if I could get them to work. We will certainly need bidirectional communication. The example has load and save methods, the idea is that system services are exposed to applications at this level.
var http = require("http");
var fs = require('fs');
var static = require('node-static');
var savedPath = "/home/marcopg/Development/tmp/saved";
function load(request, response) {
response.end(fs.readFileSync(savedPath, "binary"));
}
function save(request, response) {
data = "";
request.setEncoding("binary");
request.on("data", function(chunk) {
data += chunk;
})
request.on("end", function() {
fs.writeFileSync(savedPath, data, "binary");
})
}
var file = new(static.Server)("./apps");
http.createServer(function (request, response) {
if (request.url == "/save") {
save(request, response);
} else if (request.url == "/load") {
load(request, response);
} else {
file.serve(request, response);
}
}).listen(8080, "localhost");
console.log('Server running at http://localhost:8080');
Then the editor application. Some trivial HTML And bits of javascript to talk to the server. On startup we load the current text by making an XMLHttpRequest to the engine. Similarly, when the “Save” button is pressed we send it to the server with a POST request.
<html>
<head>
<script type="text/javascript" src="editor.js"></script>
</head>
<body onLoad="load();">
<form>
<textarea id="textArea" rows="10" cols="50"></textarea>
<p>
<input type="button" onClick="save();" value="Save"/>
</p>
</form>
</body>
</html>
function load() {
var xhr = new XMLHttpRequest();
xhr.open("GET", "load");
xhr.send();
xhr.onreadystatechange = function (aEvt) {
if (xhr.readyState == 4) {
var textArea = document.getElementById("textArea");
textArea.value = this.responseText;
}
}
}
function save() {
var textArea = document.getElementById("textArea");
var xhr = new XMLHttpRequest();
xhr.open("POST", "save");
xhr.send(textArea.value);
}
Finally a viewer, based on WebKit2. As you can see their new API is pretty nice, it’s all C and it’s supposed to be stable. It should be a lot less painful to maintain than hulahop.
#include <WebKit2/WebKit2.h>
#include <gtk/gtk.h>
#define HOME_URL "http://localhost:8080/editor.html"
int main(int argc, char *argv[])
{
GtkWidget *window;
GtkWidget *box;
WKViewRef web_view;
if (!g_thread_supported())
g_thread_init(NULL);
gtk_init(&argc, &argv);
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
box = gtk_vbox_new(FALSE, 0);
gtk_container_add(GTK_CONTAINER(window), box);
gtk_widget_show(box);
web_view = WKViewCreate(WKContextGetSharedProcessContext(), 0);
gtk_box_pack_start(GTK_BOX(box), GTK_WIDGET(web_view), TRUE, TRUE, 0);
gtk_widget_show(GTK_WIDGET(web_view));
WKPageLoadURL(WKViewGetPage(web_view),
WKURLCreateWithUTF8CString(HOME_URL));
gtk_widget_show(window);
gtk_window_fullscreen(GTK_WINDOW(window));
gtk_main();
return 0;
}
A few advantages over the standard activities framework are pretty obvious.
- You can be as creative as you like by writing the UI in HTML (and related web technologies).
- The activity is sandboxed by default, it only has access to the services exposed by the engine.
- You could run the same application on other platforms, as long as you have a viewer and an engine for it.
As I said this was just an experiment. I’m not sure I will have time to work on it again, but if I do these are the things I would probably be working on first.
- Write instructions on how to build and run the thing.
- Hack a Sugar HIG compliant UI. I will need to figure out how to share widgets and artwork between applications.
- Expose activity metadata in the viewer, so that it actually integrates with the Sugar shell.
- Add a datastore interface to the engine in place of the toy load/save methods.
The code is in a git repository if you want to play with it.
I want sugar to be a lot easier to build from source. It’s slow and fragile right now and I suspect it’s one of the basic bottlenecks to contributions. I started by documenting what I would like it to be.
I worked on it during the weekend and achieved my first goal. It builds flawlessly on a clean Lucid virtual machine. It just required to merge the git modules, the various configure.ac and trivial changes to each module. As you might have guessed this is heavily inspired by Michael StoneĀ omnibus sugar repository, credits and thanks to him.
Goal for this week, make it actually run
My mail vs code ratio is incredibly bad these days. Next thing I’m going to do is to to setup a dev environment