Almost 8 months ago we offered a brand new turpial version, with a lot of new features: Multiple accounts, unlimited columns and a really good looking interface. That looked promising, however it was an unkwon path for us. Very innovator but very uncertain. Guess what? We stucked up. Yes, Webkit let you do anything you want, imagination is the limit, but as the uncle Ben said: “With great power comes great responsabilities”. And that quote never had such a big meaning for me as now. This apparently unlimited power requires a extremely solid base of development and in our case, we hadn’t.
First approach First thing I had to deal with was Webkit and threads. Threads? Yes sir, threads. Threading is the only way you can do a long task without freezing the whole UI, it’s not very pleasant to get a gray and useless window while your app is fetching your timelime, for example. At he beginning was very frustrating and I got “solutions” like: “You have to enclose all the methods that access the UI from the thread with this”:
gtk.threads_leave() Can you imagine doing so for every single method that should access to UI widgets? It’s at least overwhelming. I continued my research and after like 2 weeks of frantic reading I finally got a reasonable explanation: Gtk is thread-aware not thread-safe, so you just need to start the threads support and enclose the main loop with those instructions and Gtk will know what to do. Ok the code was simple, at the beginning of your file do this:
gtk.threads_init() And then enclose your main loop with this:
Passing arguments Intercepting clicks wasn’t the end, it was just the beginning. Despite the idea of calling Python methods from URLs in HTML seems motivating, we faced a new challenge: Passing arguments to those Python methods. I say a “challenge” because we only could build links, so arguments should be passed as a part of the link and then parsed out. After lot of testing I decided to implement this schema:
cmd://method_name-%&%-argument1-%&%-argument2... Where -%&%- acts as arguments separator. “Why such a complicated characters sequence?” You may ask. Well, because I thought that making a hard sequence is less probable that parsing fails by misunderstanding the separator with the content of one argument. I tried with simpler separators and base64 encoding but we needed to pass other params (like status messages) that have a lot of non-ASCII chars and base64 is not very good for that. For those arguments I ended using URL encoding. At the moment of writing this I think that maybe a better solution could be making RESTful links, this means to use slashes (/) as separators and URL encoding each argument. Like this: cmd://method_name/url_encoded_argument1/url_encoded_argument2/url_encoded_argument3/… But, hey! it’s done. Now I’m relaxed, working on GTK3 migration and probably my brain is not under stress. Sh*t happens.
execute_script method to update the DOM of the page. Everytime you use that method your memory increases a little bit. Tweets were keeping in memory (in an array) and in HTML view ad infinitum, making the memory grows and grows until the OS decided to close the application. Turpial 1.6.x used like 50~60MB of RAM but Turpial 2 was using almost 100MB of RAM while applications like Banshee were using 60MB and gnome-shell 120MB. For my this was unacceptable for a “lightweight” application. This issue taugh me that PyWebkitGtk implementation was not so good as I expected, it lacks of documentation (the only available is the C++ documentation) and that if you want to develop complex applications on top of it you should think twice.
Conclusion It was a really good experience (in terms of learning) but all the issues explained above make me take the decision of drop the webkit support and back to the limited but stable-and-well-known GTK3 in order to deliver a new Turpial version as soon as possible. Turpial 1.6.9 has been out there for more than 1 year and it’s time to release a fresh version of the bird. Webkit is a really powerful tool, I have no doubt about it. You can build anything on top of HTML and present the same look & feel for all platforms, besides using CSS you can implement a theme engine easily. However the complexity of the integration, the frustration you have to deal with everytime you want to make changes on your layout and it breaks and the performance issues put Webkit out of my list of tools for Turpial. Probably I could use it, but not for Turpial. For using Webkit as we want we need a framework, limited and bounded that minimize all the suffering and offer you a stable tool for development. That’s all folks, I hope this article can be helpful for someone else.
Time of death: October 10, 2012
If you are interested on this topic you can read more here:
- First Turpial 2.0 official announcement
- First 2.0 alpha release/
- Alpha release delayed
- Mailing list thread about performance issues
- Mailing list thread about Gtk3 migration
- Official announcement of Gtk3 migration
- Interesting article about Web interfaces with Python
- GNOME explanation about Gtk threading awareness