Skip to content
GNOME Gtk+ bindings for NodeJS
Branch: master
Clone or download
Pull request Compare This branch is 530 commits ahead, 13 commits behind WebReflection:master.
romgrk Merge pull request #122 from romgrk/promise-issue
fix #121: promise microtasks not called
Latest commit 6da8aff Jun 7, 2019
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
doc doc: update maintainers.md May 18, 2019
examples loop: fix promise not called issue Jun 7, 2019
img replace browser.png Jul 18, 2018
lib loop: fix promise not called issue Jun 7, 2019
scripts build.sh: fix skip-tests bug Jan 22, 2019
src loop: remove forward declaration Jun 7, 2019
tests tests: fix gdkRgba timeout May 18, 2019
.env update .env Jul 22, 2018
.eslintrc.json add eslintrc Jun 7, 2018
.gitignore add package-lock.json & clean deps Jul 30, 2018
.travis.yml travis: add node 12 May 17, 2019
CHANGELOG.md changelog: update Jun 5, 2019
COPYING
README.md readme: update May 18, 2019
binding.gyp implement system module Jan 23, 2019
node-gtk.doap renamed to node-gtk Dec 17, 2015
package-lock.json 0.3.0 May 18, 2019
package.json package: add .files May 18, 2019

README.md

node-gtk

GNOME Gtk+ bindings for NodeJS

NPM version

What is this

A work in progress to bring Gtk+ usable directly from nodejs so that the environemnt would be more udated and supported than the one available via GJS. It uses the GObject Introspection library (as PyGObject, for example), so any gobject-introspectable library is supported.

Please note this project is currently in beta state and is being developped. Any contributors willing to help will be welcomed.

Supported Node.js versions: 8, 9, 10, 11, 12
Pre-built binaries available for: Linux, OS X

How do I use it?

You can use Gtk+ API directly, or you can use react-gtk to develop a node-gtk application using React.

Browser demo Browser demo source

Table of contents

Example

const gi = require('node-gtk')
Gtk = gi.require('Gtk', '3.0')

gi.startLoop()
Gtk.init()

const win = new Gtk.Window();
win.on('destroy', () => Gtk.mainQuit())
win.on('delete-event', () => false)

win.setDefaultSize(200, 80)
win.add(new Gtk.Label({ label: 'Hello Gtk+' }))

win.showAll();
Gtk.main();

Hello node-gtk!

Documentation

Exports

require(ns, [version])Object

Requires a module. Automatically loads dependencies.

prependSearchPath(path)

Prepends a path to GObject-Introspection search path (for typelibs)

prependLibraryPath(path)

Prepends a path to GObject-Introspection library path (for shared libraries)

require(ns, [version]) ⇒ Object

Requires a module. Automatically loads dependencies.

Returns: Object - the loaded module

Param Type Default Description
ns string namespace to load
version string null version to load (null for latest)

prependSearchPath(path)

Prepends a path to GObject-Introspection search path (for typelibs)

Param Type
path string

prependLibraryPath(path)

Prepends a path to GObject-Introspection library path (for shared libraries)

Param Type
path string

Signals (event handlers)

Signals (or events, in NodeJS semantics) are dispatched through the usual .on, .off, and .once methods.

Returning true from an event handler can have the special semantic of stopping the event from being propagated or preventing the default behavior. Refer to GTK documentation for details. (E.g. GtkWidget signals)

const input = new Gtk.Entry()

/**
 * GObject.on - associates a callback to an event
 * @param {String} name - Name of the event
 * @param {Function} callback - Event handler
 */
input.on('key-press-event', onKeyPress)

/**
 * GObject.off - dissociates callback from an event
 * @param {String} name - Name of the event
 * @param {Function} callback - Event handler
 */
input.off('key-press-event', onKeyPress)

/**
 * GObject.once - as GObject.on, but only runs once
 * @param {String} name - Name of the event
 * @param {Function} callback - Event handler
 */
input.once('key-press-event', onKeyPress)


function onKeyPress(event) {
  // event.__proto__ === Gdk.EventKey
  console.log(event.string, event.keyval)
}

Low-level methods .connect(name: String, callback: Function) : Number and .disconnect(name: String, handleID: Number) : void are also available.

Gtk

For GTK objects and functions documentation, please refer to gnome documentation, or any other GIR generated documentation as valadoc.

Naming conventions

  • Functions, Methods & Virtual Functions: lowerCamelCase
    Methods on GObject, structs, unions and functions on namespaces.
    Example:
    GLib.randomIntRange(0, 100)
    textBuffer.placeCursor(0)

  • Fields & Properties: lowerCamelCase
    Fields are on structs and unions.
    Properties are on GObjects.
    Example:
    textView.showLineNumbers = true
    new Gdk.Color().blue = 200

  • Structs, Unions, GObjects & Interfaces: UpperCamelCase
    Defined on namespaces.
    Example:
    Gtk.Button
    Gdk.Color

  • Enums, Flags: UpperCamelCase
    Defined on namespaces.
    Example:
    Gtk.AttachOptions
    Gdk.EventType

  • Constants & Values: SNAKE_CASE (not modified, may contain lowercase)
    Can be attached on namespaces or on specific objects.
    Example:
    Gdk.KEY_g !== Gdk.KEY_G
    Gdk.EventType.KEY_PRESS

  • Signals: dash-case
    Events triggered by GObjects.
    Example:
    gtkEntry.on('key-press-event', (ev) => { ... })

Installing and building

Target Platforms (so far)

We're planning to serve pre-built binaries in order to make this project as cross platform and easy to install as possible. However, right now we support only Linux and experimentally OSX but in both targets the project will falback to build.

Requirements

In order to clone, install, and build this project you'll need a working copy of git, nodejs 8 or higher, npm, python2, and either gcc 8 (other versions may fail) or clang. In the not-working-yet Windows platform, all dependencies must be available under MSYS2 shell.

How to build on Ubuntu

Be sure node is version 8 or higher. Ignore the following step iv node --version is already 8 or higher.

# setup node 10
curl -sL https://deb.nodesource.com/setup_10.x | sudo -E bash -

Install basic dependencies.

# install dependencies
sudo apt-get install \
  build-essential git \
  nodejs \
  gobject-introspection \
  libgirepository1.0-dev

At this point npm install node-gtk should already install, fallback and build node-gtk without problems.

How to build on Fedora

Install basic dependencies:

sudo dnf install \
  @development-tools \
  nodejs \
  gobject-introspection \
  gtk3

After installing of packages, run npm install node-gtk.

How to build on ArchLinux

The following should be the bare minimum to be able to build the project.

pacman -S --needed \
  base-devel git \
  nodejs npm \
  gtk3 gobject-introspection

Feel free to install all base-devel utilities.

After installing those packages, npm install node-gtk would do.

How to build on OSX

Assuming you have brew installed, the following has been successfully tested on El Captain.

# basic dependencies to build this repo
brew install git node gobject-introspection gtk+3

At this point npm install node-gtk should already install, fallback and build node-gtk without problems.

Testing the project

If you'd like to test everything builds and work properly, find a target to clone this project, then run npm install.

# clone and build
git clone https://github.com/romgrk/node-gtk.git
cd node-gtk
npm install

# how to verify from node-gtk folder
./examples/hello-gtk.js

If you'll see a little window saying hello that's it: it works!

Please note in OSX the window doesn't automatically open above other windows. Try Cmd + Tab if you don't see it.

Browser demo

If you'd like to test ./examples/browser.js you'll need WebKit2 GTK+ libary.

  • in Ubuntu, you can apt-get install libwebkit2gtk-3.0 (4.0 works too) and try it out.
  • in Fedora, you should run sudo dnf install webkit2gtk3
  • in ArchLinux, you can pacman -S --needed webkitgtk and try it out.
  • in OSX, there is no way to run it right now because webkitgtk was removed from homebrew

Once installed, you can ./examples/browser.js google.com or any other page, and you might try the dark theme out too:

# OSX needs to have the Adwaita theme installed
# brew install adwaita-icon-theme

# Usage: ./examples/browser.js <url> [theme]
./examples/browser.js  google.com  dark

Experimental platforms

Following how to setup the configuration to at least try building this project.

How to build on Windows (experimental)

Mandatory dependency is Visual Studio Community or Express with a C++ compiler (open a new C++ project and install it via IDE if necessary).

The easiest/tested way to at least try building this repository is within a MinGW shell provided by the MSYS2 installer.

Once VS and its C++ compiler is available and MSYS2 installed, launch the MinGW shell.

# update the system
# in case of errors, wait for the update to complete
# then close and open again MingW shell
pacman -Syyu --noconfirm

# install git, gtk3 and extra dependencie
pacman -S --needed --noconfirm git mingw-w64-$(uname -m)-{gtk3,gobject-introspection,pkg-config}

# where to put the repository clone?
# pick your flder or use ~/oss (Open Source Software)
mkdir -p ~/oss/
cd ~/oss

# clone node-gtk there
git clone https://github.com/romgrk/node-gtk
cd node-gtk

# first run might take a while
GYP_MSVS_VERSION=2015 npm install

The GYP_MSVS_VERSION could be 2010, 2012, 2013 or 2015. Please verify which version you should use

Possible issue on MinGW shell

In case you are launching the general executable without knowing the correct platform, the binary path might not be available.

In such case python won't be available neither, and you can check via which python command.

If not found, you need to export the platform related binary path:

# example for the 32bit version
export PATH="/mingw32/bin:$PATH"
npm run install

This should do the trick. You can also check if there is any python at all via pacman -Qs python.

Please remember python2 is the one needed.

known issues building on Windows

Right now there are few gotchas and the build will most likely fail. Please help with a PR if you know how to solve the issue, thank you!

Support

There are still less used features that are not supported, but everything you should need to start building a working Gtk application is supported.

  • primitive data types (int, char, …)
  • complex data types (arrays, GArray, GList, GHashTable, …)
  • GObjects
  • Interfaces: methods on GObjects
  • Interfaces: raw C struct conversion to JS
  • Signals (.connect('signal', cb) or .on('signal', cb))
  • Boxed (struct and union) (opaque, with new)
  • Boxed (struct and union) (opaque, without new)
  • Boxed (struct and union) (allocation with size)
  • Error handling
  • Callback arguments
  • Function call: IN, OUT & INOUT arguments
  • Properties (on GObjects)
  • Fields (on Boxeds)
  • Event loop (main)
  • Additional event loops (e.g. g_timeout_add_seconds)
  • GParamSpec
  • Javascript inheritance of C classes
  • Memory management
You can’t perform that action at this time.