36

I am developing an app and I think HTML and JavaScript are better for the future, but I cannot find any tutorials (I need the app to use the system theme).

Are there bindings for Unity, message menu and notification, couchdb and so on?

1

7 Answers 7

25

A good starting point for bindings and APIs on Ubuntu can be found on developer.ubuntu.com. I don't have any experience with it, but you will probably also want to look into Gjs, the Javascript bindings for GNOME.

Depending on what you are trying to do, you could just build the app like any HTML + JS app and then throw it into a Webkit view. It's extremely simple to do in python:

#!/usr/bin/env python

from gi.repository import Gtk, WebKit
import os, sys

class Browser:
    def __init__(self):
        self.window = Gtk.Window()
        self.window.set_default_size(800, 600)
        view = WebKit.WebView()
        view.load_html_string("<strong>Hello World!</strong>", "file:///")  
        self.window.add(view)

        self.window.show_all()
        self.window.connect('destroy', lambda w: Gtk.main_quit())

def main():
    app = Browser()
    Gtk.main()

if __name__ == "__main__":
    main()
1
  • 8
    JS is real programming too.
    – Owais Lone
    Aug 28, 2011 at 19:33
17

You can develop using HTML + Javascript for the interface by using an embedded WebKit frame in a Gtk window (this is easiest to do in Python). The hardest part is communicating with the system from your HTML/Javascript application.

You can do this by passing messages between Javascript and Python. You will, however, have to write the system logic as Python functions but this is pretty easy to do.

Here is a simple example showing communication between Python and Javascript. In the example, the HTML/Javascript displays a button, that when clicked sends an array ["hello", "world"] to Python which joins the array into a string "hello world" and sends it back to Javascript. The Python code prints a representation of the array to the console and the Javascript code pops up an alert box that displays the string.

example.py

import gtk
import webkit
import json
import os

JAVASCRIPT = """
var _callbacks = {};
function trigger (message, data) {
    if (typeof(_callbacks[message]) !== "undefined") {
        var i = 0;
        while (i < _callbacks[message].length) {
            _callbacks[message][i](data);
            i += 1;
        }
    }
}
function send (message, data) {
    document.title = ":";
    document.title = message + ":" + JSON.stringify(data);
}
function listen (message, callback) {
    if (typeof(_callbacks[message]) === "undefined") {
        _callbacks[message] = [callback];
    } else {
        _callbacks[message].push(callback);
    }
}
"""

class HTMLFrame(gtk.ScrolledWindow):
    def __init__(self):
        super(HTMLFrame, self).__init__()
        self._callbacks = {}
        self.show()
        self.webview = webkit.WebView()
        self.webview.show()
        self.add(self.webview)
        self.webview.connect('title-changed', self.on_title_changed)

    def open_url(self, url):
        self.webview.open(url);
        self.webview.execute_script(JAVASCRIPT)

    def open_path(self, path):
        self.open_url("file://" + os.path.abspath(path))

    def send(self, message, data):
        self.webview.execute_script(
            "trigger(%s, %s);" % (
                json.dumps(message),
                json.dumps(data)
            )
        )

    def listen(self, message, callback):
        if self._callbacks.has_key(message):
            self._callbacks[message].append(callback)
        else:
            self._callbacks[message] = [callback]

    def trigger(self, message, data, *a):
        if self._callbacks.has_key(message):
            for callback in self._callbacks[message]:
                callback(data)

    def on_title_changed(self, w, f, title):
        t = title.split(":")
        message = t[0]
        if not message == "":
            data = json.loads(":".join(t[1:]))
            self.trigger(message, data)

def output(data):
    print(repr(data))    

if __name__ == "__main__":
    window = gtk.Window()
    window.resize(800, 600)
    window.set_title("Python Gtk + WebKit App")
    frame = HTMLFrame()
    frame.open_path("page.html")
    def reply(data):
        frame.send("alert", " ".join(data))
    frame.listen("button-clicked", output)
    frame.listen("button-clicked", reply)
    window.add(frame)
    window.show_all()
    window.connect("destroy", gtk.main_quit)
    gtk.main()

page.html

<html>
<body>
<input type="button" value="button" id="button" />
<script>
document.getElementById("button").onclick = function () {
    send("button-clicked", ["hello", "world"]);
};
listen("alert", function (data) {alert(data);});
</script>
</body>
</html>     

The only python code you really need to pay attention to here is the code from def output(data): to the end of the file which should be pretty easy to understand.

To run this make sure python-webkit and python-gtk2 are installed then save the files in the same folder and run:

python example.py

program in action

1
5

I developed BAT, which is a tiny tool for building desktop applications with HTML, JS and CSS.


I wrote an article about it on my blog.

Example

index.html

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <style>
            body {
                font-family: Monaco, monospace;
                color: white;
                background: #3C3B38;
            }
            h1 { text-align: center; }
            p { text-align: justify; }
            button {
                padding: 10px 20px;
                -moz-border-radius: 4px 4px 4px 4px;
                -webkit-border-radius: 4px 4px 4px 4px;
                border-radius: 4px 4px 4px 4px;
                display: block;
                font-size: 14px;
                text-decoration: none;
                border: 1px solid #c0b7b0;
                cursor: pointer;
                width: 100%;
            }
        </style>
    </head>
    <body>
        <h1>Hello World</h1>
        <p> Ipsum deserunt architecto necessitatibus quasi rerum dolorum obcaecati aut, doloremque laudantium nisi vel sint officia nobis. Nobis ad nemo voluptatum molestiae ad. Nisi ipsum deserunt a illo labore similique ad?  </p>
        <p> Ipsum veniam laborum libero animi quo dignissimos. Possimus quidem consequatur temporibus consequatur odio, quidem deleniti! Similique totam placeat sint assumenda nulla dolor. Voluptatibus quasi veritatis distinctio consectetur nobis. Nemo reprehenderit?  </p>
        <p> Ipsum molestiae nesciunt commodi sint et assumenda recusandae! Earum necessitatibus sequi nulla fugit architecto omnis. Maiores omnis repellat cupiditate iure corporis dolorem sed amet nesciunt. Mollitia sapiente sit repellendus ratione.  </p>
        <p> Consectetur architecto ratione voluptate provident quis. At maiores aliquam corporis sit nisi. Consectetur ab rem unde a corporis reiciendis ut dolorum, tempora, aut, minus. Sit adipisci recusandae doloremque quia vel!  </p>
        <button onclick="BAT.closeWindow()">Close</button>
    </body>
</html>

And, we run it this way:

bat -d index.html -t "BAT Hello World" -s 800x500

The result is:

4

As far as accessing the platform directly, you should check out Seed.

You might also take a look at UserWebKit, the Python3 library that provides the key functionality used by the Novacut and Dmedia UI (it's built atop UserCouch and Microfiber, BTW).

After a lot of thought, I decided it was more interesting to not access the platform directly from JavaScript, because then you can optionally run the UI in a standard browser if you want. The Novacut architecture uses CouchDB to keep the UI and backend servers network-transparent. In the normal, single-computer case, the servers run locally on that computer. But you can likewise run the servers (and CouchDB) on other systems, without the UI noticing the difference.

3

Well you could include a language that can run shell commands like php and this way take advantage of stuff like installing apps from a webpage and executing some commands (Like detecting which theme to use and what CSS to use depending on the system theme). For example you have this two questions which might help:

Can a server handle simultaneous shell commands? (Which talks about executing multiple commands)

Run a line command from a web (Clicking in a webpage link) (Which talks about clicking on a link and installing an app from the software center)

For a way to learn what theme is used you could parse the ubuntu file where it has the value for the default theme and depending on it modify the CSS of the site to reflect the new theme.

Questions about theme and where to find it can be found here:

What file I need to edit to change the text color in a theme?

Desktop forgets theme?

Editing GTK theme (adding a border)

All of this (and more if you use the search) help you know where to look when parsing and what files you can check to see what theme the system is using and what to use in the web page then.

2

Yes, you can write apps in pure html/css/js and yes binding are available for JS using GObject introspection. Take a look at GnomeSeed https://live.gnome.org/Seed

SeedKit: https://live.gnome.org/SeedKit

Tutorial: https://live.gnome.org/Seed/Tutorial

0

Now we have AppJS -- https://github.com/milani/appjs !

As they said, "It uses Chromium as the core (so that the latest HTML5 APIs are supported) and Node.js as the backbone."

You must log in to answer this question.