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
You can use Gtk+ API directly, or you can use react-gtk to develop a node-gtk
application using React.
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();
- 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)
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) |
Prepends a path to GObject-Introspection search path (for typelibs)
Param | Type |
---|---|
path | string |
Prepends a path to GObject-Introspection library path (for shared libraries)
Param | Type |
---|---|
path | string |
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.
For GTK objects and functions documentation, please refer to gnome documentation, or any other GIR generated documentation as valadoc.
-
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) => { ... })
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.
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.
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.
Install basic dependencies:
sudo dnf install \
@development-tools \
nodejs \
gobject-introspection \
gtk3
After installing of packages, run npm install node-gtk
.
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.
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.
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.
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
Following how to setup the configuration to at least try building this project.
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
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.
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!
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