This Emscripten/webassembly port of GLFW tries to implement as much of the GLFW API that is possible to implement in the context of a web browser. See the list of all functions with some notes for details. This page documents the most important aspects of the library.
This port, as well as other library ports (like SDL), associates the concept of a "window" (in this instance
a GLFWwindow
) to an HTML "canvas". The framebuffer size of the window is the size of the canvas
(canvas.width
x canvas.height
) and this is what you use for your viewport.
The size of the window is the CSS style size of the canvas (which in the case of Hi DPI is different). The opacity
is the CSS style opacity
, etc...
Important
Once the canvas is associated with the window, the library takes control over it and sets various listeners and CSS styles on the canvas. In particular, the width and height are controlled by the library and as a result this implementation offers another mechanism for the user to be able to resize the canvas.
Natively, GLFW doesn't know anything about the concept of a canvas. So there needs to be a way to make this association. This library offers 2 ways depending on your needs:
Every Emscripten application needs to define a Module
variable in JavaScript (see example).
By convention in Emscripten, the Module["canvas"]
field represents the canvas associated to the window.
To be backward compatible with this option, this library supports it, and it is the default. Obviously, this can only
work if there is only one window, which is why there is another method.
This implementation offers an alternative way of specifying which canvas to associate to which window: the function
emscripten::glfw3::SetNextWindowCanvasSelector
which must be called prior to calling glfwCreateWindow
. The
single argument to the function is a CSS path selector to the canvas.
Example:
#include <GLFW/emscripten_glfw3.h> // contains the definitions
emscripten::glfw3::SetNextWindowCanvasSelector("#canvas1");
auto window1 = glfwCreateWindow(300, 200, "hello world", nullptr, nullptr);
This function is required if you use more than one window since the Module
solution only supports 1 canvas.
It also offers the advantage of defining the association in C/C++ as opposed to HTML/JavaScript.
GLFW deals with windows. Windows, in the context of a desktop application, are usually resizable by the user (note that
the GLFW window hint/attribute GLFW_RESIZABLE
lets you disable this feature). So how does this translate into the
HTML/canvas world?
To make the canvas resizable, and behave more like a "traditional" window, this implementation offers a
convenient API: emscripten::glfw3::MakeCanvasResizable
:
int MakeCanvasResizable(GLFWwindow *window,
std::string_view canvasResizeSelector,
std::optional<std::string_view> handleSelector = std::nullopt);
Since this library takes control of the canvas size, the idea behind this function is to specify which
other (HTML) element dictates the size of the canvas. The parameter canvasResizeSelector
defines the
(CSS path) selector to this element.
The 3 typical use cases are:
The canvas fills the entire browser window, in which case the parameter canvasResizeSelector
should simply
be set to "window" and the handleSelector
is std::nullopt
.
This use case can be found in application like ImGui where the canvas is the window.
Example code:
<!-- html -->
<canvas id="canvas1"></canvas>
// cpp
emscripten::glfw3::SetNextWindowCanvasSelector("#canvas1");
auto window = glfwCreateWindow(300, 200, "hello world", nullptr, nullptr);
emscripten::glfw3::MakeCanvasResizable(window, "window");
The canvas is inside a div
, in which case the div
acts as a "container" and the div
size is defined by
CSS rules, like for example: width: 75vw
so that when the page/browser gets resized, the div
is resized
automatically, which then triggers the canvas to be resized. In this case, the parameter canvasResizeSelector
is the (CSS path) selector to this div
and handleSelector
is std::nullopt
.
Example code:
<!-- html -->
<style>
#canvas1-container {
width: 75vw;
height: 50vh;
}
</style>
<div id="canvas1-container">
<canvas id="canvas1"></canvas>
</div>
// cpp
emscripten::glfw3::SetNextWindowCanvasSelector("#canvas1");
auto window = glfwCreateWindow(300, 200, "hello world", nullptr, nullptr);
emscripten::glfw3::MakeCanvasResizable(window, "#canvas1-container");
Same as 2. but the div
is made resizable dynamically via a little "handle" (which ends up behaving like a
normal desktop window).
Example code:
<!-- html -->
<style>
#canvas1-container {
position: relative;
<!-- . . . -->
}
#canvas1-handle {
position: absolute;
bottom: 0;
right: 0;
margin-bottom: 1px;
margin-right: 1px;
border-left: 20px solid transparent;
border-bottom: 20px solid rgba(102, 102, 102, 0.5);
width: 0;
height: 0;
cursor: nwse-resize;
z-index: 1;
}
</style>
<div id="canvas1-container">
<div id="canvas1-handle" class="handle"></div>
<canvas id="canvas1"></canvas>
</div>
// cpp
emscripten::glfw3::SetNextWindowCanvasSelector("#canvas1");
auto window = glfwCreateWindow(300, 200, "hello world", nullptr, nullptr);
emscripten::glfw3::MakeCanvasResizable(window, "#canvas1-container", "canvas1-handle");
Tip
If you do not want the canvas to be resizable by the user, you can simply set its size during window creation
(glfwCreateWindow
) or with glfwSetWindowSize
and don't do anything else.
GLFW has a concept of a fullscreen window.
This is quite tricky for this implementation due to the restrictions imposed by browsers to go fullscreen.
Historically, Emscripten has offered a way to do it from JavaScript by the means of a
function that gets added automatically to the Module
called requestFullscreen
.
This implementation adds another JavaScript function Module.glfwRequestFullscreen(target, lockPointer, resizeCanvas)
with
target
being which canvas need to be fullscreenlockPointer
: boolean to enable/disable grabbing the mouse pointer (equivalent to callingglfwSetInputMode(GLFW_CURSOR, xxx)
)resizeCanvas
: boolean to resize (or not) the canvas to the fullscreen size
To be backward compatible with the current Emscripten/GLFW/JavaScript implementation, you can also call
Module.requestFullscreen(lockPointer, resizeCanvas)
and the library does its best to determine which
canvas to target.
This implementation also offers a CPP and C version of this API:
void emscripten::glfw3::RequestFullscreen(GLFWwindow *window, bool lockPointer, bool resizeCanvas);
void emscripten_glfw_request_fullscreen(GLFWwindow *window, bool lockPointer, bool resizeCanvas);
Tip
To avoid any error while switching to fullscreen, you should always trigger this api from within a user event
like a mouse click (callback set via glfwSetMouseButtonCallback
)
or a keyboard key press (callback set via glfwSetKeyCallback
)
At this moment, this implementation does not support creating a window in fullscreen mode due to the same browser
restrictions mentioned previously. If you want to create a fullscreen window, create a window with a fixed size,
then from a user event call Module.glfwRequestFullscreen
.
This implementation supports Hi DPI awareness. What this means is that if the browser window is on a screen that is
Hi DPI/4k, then it will properly adjust the dimension of the canvas to match the scale of the screen. If the window gets
moved to a screen that is lower resolution, it will automatically change the scaling. You can set a callback to be
notified of the changes (glfwSetWindowContentScaleCallback
) or call the direct API glfwGetWindowContentScale
.
By default, this feature is enabled and can be turned off like this:
// before creating a window (to turn Hi DPI Awareness OFF)
glfwWindowHint(GLFW_SCALE_FRAMEBUFFER, GLFW_FALSE);
auto window = glfwCreateWindow(...);
// after window creation, it can be dynamically changed
glfwSetWindowAttrib(window, GLFW_SCALE_FRAMEBUFFER, GLFW_TRUE); // for enabling Hi DPI awareness
glfwSetWindowAttrib(window, GLFW_SCALE_FRAMEBUFFER, GLFW_FALSE); // for disabling Hi DPI awareness
Note
The constant GLFW_SCALE_FRAMEBUFFER
was introduced in GLFW 3.4. The constant GLFW_SCALE_TO_MONITOR
which was
used prior to GLFW 3.4, can still be used to trigger Hi DPI Awareness, but is less descriptive and as a result it
is deprecated, and it is preferable to use GLFW_SCALE_FRAMEBUFFER
.
Tip
Almost all GLFW apis deal with screen coordinates which are independent of scaling.
The only one that doesn't is glfwGetFramebufferSize
which returns the actual size of the surface which takes into account the scaling factor.
As a result, for most low-level APIs (like OpenGL/webgl) you would use this call to set the viewport size.
Here is an example:
int width = 0, height = 0;
glfwGetFramebufferSize(fWindow, &width, &height);
glViewport(0, 0, width, height);
This implementation supports the keyboard and uses the same mapping defined in Emscripten for scancodes. You can check
KeyboardMapping.h for the full mapping. This implementation uses KeyboardEvent.key
to compute an accurate
codepoint (provided to the GLFWcharfun
callback) and not the deprecated KeyboardEvent.charcode
like other
implementations.
Internally, the library uses the keyboard events provided by JavaScript and calls e.preventDefault()
on all
keyboard events except for the 3 keyboard shortcuts associated with cut, copy and paste (based on the runtime platform:
⌘ + C, ⌘ + X + ⌘ + V, for macOS and ^ + C, ^ + X, ^ + V for the other platforms).
In particular, this allows an application written using this library to automatically ignore ^ + F (resp. ⌘ + F) which displays a "Find in page" interface, which is usually not desirable nor useful (a canvas is not searchable).
In the event you want to change this behavior, you can add your own callback by calling
emscripten::glfw3::AddBrowserKeyCallback()
or entirely replace it with emscripten::glfw3::SetBrowserKeyCallback()
.
The callback is called on key down, key repeat and key up and should return true
for the event to bubble up to
the browser (e.preventDefault()
will not be called).
Here is an example:
// Allow the F12 key to bubble up to the browser (open developer tools in Chrome):
emscripten::glfw3::AddBrowserKeyCallback([](GLFWwindow* window, int key, int scancode, int action, int mods) {
return mods == 0 && action == GLFW_PRESS && key == GLFW_KEY_F12;
});
Note
At this time, GLFW_MOD_CAPS_LOCK
and GLFW_MOD_NUM_LOCK
are not supported.
The key called "Super" by the GLFW library (also known as Meta or Command) exhibits an issue in the context of the
browser: pressing any other regular key (like the key A
) while "Super" is being held, properly triggers down and
repeat events, but never triggers the up event.
This library implements a workaround to detect this scenario by setting internal timeouts.
These values can be read and modified via the emscripten::glfw3::GetSuperPlusKeyTimeouts()
and
emscripten::glfw3::SetSuperPlusKeyTimeouts()
APIs.
In addition to timeouts, when the "Super" key is released, all keys are also released.
Tip
It is strongly recommended for your application to set a key callback (glfwSetKeyCallback
) since you get
notifications on key down and key repeat, based on the values set at the OS level instead of trying to implement
key repeat manually.
This implementation uses the JavaScript Gamepad
API as defined in the specification
which is widely supported by most current browsers.
Important
Due to the nature of the Gamepad
API, polling is required, so you must ensure to call glfwPollEvents
on each
loop iteration.
If you want to disable joystick support entirely (and save some resources), you can use the disableJoystick=true
option if you use the port (or set the EMSCRIPTEN_GLFW3_DISABLE_JOYSTICK
compilation define).
This image, represents the mapping returned by this API (as defined here):
- If you use the
glfwGetJoystickAxes
andglfwGetJoystickButtons
functions, you get exactly this mapping - The function
glfwGetJoystickGUID
returnsGamepad.mapping
andglfwJoystickIsGamepad
returnsGLFW_TRUE
when the mapping is"standard"
- The function
glfwGetJoystickHats
maps the standard gamepad mapping to theGLFW_HAT_XXX
bitfield
Caution
The function glfwGetGamepadState
returns the same information that glfwGetJoystickAxes
and
glfwGetJoystickButtons
but with the mapping specified by GLFW. Although very close to the Gamepad
mapping,
there are differences, so make sure you use the API that suits your needs. For example
GLFW_GAMEPAD_BUTTON_GUIDE
is 8 but the Gamepad guide is 16!
Example:
int count;
auto buttons = glfwGetJoystickButtons(jid, &count);
auto isGuidePressed = count > 16 && buttons[16];
// versus
GLFWgamepadstate state;
auto isGuidePressed = glfwGetGamepadState(jid, &state) == GLFW_TRUE && state.buttons[GLFW_GAMEPAD_BUTTON_GUIDE];
In the context of the browser, getting access to the clipboard is a bit tricky as there are restrictions imposed by the browser for obvious security reasons.
This implementation maintains an "internal" clipboard, one that is always available whether the browser is authorized or not to access the external clipboard.
In addition, the library registers clipboard event listeners to properly handle cut, copy and paste from outside.
What this means in practice is that if your application calls glfwGetClipboardString
(resp. glfwSetClipboardString
) after detecting the same browser keyboard shortcuts for cut/copy and paste,
it simply works.
Tip
With ImGui, you can write something like this:
ImGui::GetIO().ConfigMacOSXBehaviors = emscripten::glfw3::IsRuntimePlatformApple();
It is crucial to understand that glfwGetClipboardString
does not access the clipboard live but simply
returns the value pasted by using the keyboard shortcut.
This limitation is due to the way the clipboard JavaScript API (navigator.clipboard.readText
) works,
for several reasons:
- the JavaScript API is asynchronous and
glfwGetClipboardString
is not - calling the JavaScript API results in various (purposely) intrusive popups from the browser
- these popups lead to issues (for example, Firefox shows a little "Paste" popup every time this API is called and suppresses all keyboard events, leading to missing key up events)
As a consequence, this library does not use navigator.clipboard.readText
and instead rely on the paste
event.
The proper approach for your code to handle paste, is to call glfwGetClipboardString
when the paste
keyboard event has been detected, for example:
void onKeyChange(GLFWwindow* window, int key, int scancode, int action, int mods) {
static auto kActionModifier = emscripten::glfw3::IsRuntimePlatformApple() ? GLFW_MOD_SUPER : GLFW_MOD_CONTROL;
if(action == GLFW_PRESS && (mods & kActionModifier)) {
switch(key) {
case GLFW_KEY_V: // paste
auto clipboard = glfwGetClipboardString(window);
// handle paste ....
break;
default:
// ignored
break;
}
}
}
// from main...
glfwSetKeyCallback(window, onKeyChange);
Secondly, calling glfwSetClipboardString
first sets the internal clipboard to the value provided, then attempts
to write to the external clipboard (navigator.clipboard.writeText
). In order for this latter call to succeed,
you should always call this API from a user-generated event. For example:
void onKeyChange(GLFWwindow* window, int key, int scancode, int action, int mods) {
static auto kActionModifier = emscripten::glfw3::IsRuntimePlatformApple() ? GLFW_MOD_SUPER : GLFW_MOD_CONTROL;
if(action == GLFW_PRESS && (mods & kActionModifier)) {
switch(key) {
case GLFW_KEY_X: // cut
case GLFW_KEY_C: // copy
auto selection = "..."; // compute what is currently selected
glfwSetClipboardString(window, selection);
break;
default:
// ignored
break;
}
}
}
// from main...
glfwSetKeyCallback(window, onKeyChange);
Tip
Using ImGui, if you set the keyboard behavior properly, then cut/copy and paste will work as expected on all platforms
// during initialization
ImGui::GetIO().ConfigMacOSXBehaviors = emscripten::glfw3::IsRuntimePlatformApple();
// loop
ImGui::InputText("input", buffer); // cut/copy/paste work in the widget
if(ImGui::Button("Copy to clipboard"))
ImGui::SetClipboardText("..."); // this works as well
// Note that this will NOT work well because it bypasses the paste event and as a result
// only the content of the internal clipboard is accessible!
if(ImGui::MenuItem("Paste"))
ImGui::GetClipboardText();
This implementation offers a few extensions to the normal GLFW api necessary for this specific platform.
As explained previously, some CPP functions are defined in <GLFW/emscripten_glfw3.h>
Note
All functions are defined in the emscripten::glfw3
namespace
Function | Notes |
---|---|
SetNextWindowCanvasSelector |
to specify the association window <-> canvas |
MakeCanvasResizable |
to make the canvas resizable |
UnmakeCanvasResizable |
to revert MakeCanvasResizable |
IsWindowFullscreen |
to check if the window is fullscreen |
RequestFullscreen |
to request fullscreen |
OpenURL |
to open a URL |
IsRuntimePlatformApple |
to check if the platform is Apple (ex: for keyboard shortcuts) |
AddBrowserKeyCallback |
to add a callback to bubble keys up |
SetBrowserKeyCallback |
to set a callback to bubble keys up |
GetPlatformBrowserKeyCallback |
to get the default callback for the platform |
GetSuperPlusKeyTimeouts |
to retrieve the timeouts used for the Super + key workaround |
SetSuperPlusKeyTimeouts |
to set the timeouts used for the Super + key workaround |
Similar to the CPP functions, C functions are defined in <GLFW/emscripten_glfw3.h>
, with a C-like syntax
Function | Notes |
---|---|
emscripten_glfw_set_next_window_canvas_selector |
to specify the association window <-> canvas |
emscripten_glfw_make_canvas_resizable |
to make the canvas resizable |
emscripten_glfw_unmake_canvas_resizable |
to revert emscripten_glfw_make_canvas_resizable |
emscripten_glfw_is_window_fullscreen |
to check if the window is fullscreen |
emscripten_glfw_request_fullscreen |
to request fullscreen |
emscripten_glfw_open_url |
to open a URL |
emscripten_glfw_is_runtime_platform_apple |
to check if the platform is Apple (ex: for keyboard shortcuts) |
You can either include this file, or use an extern "C" {}
section in your own code to define them
This implementation adds the following functions to the Module
:
Function | Notes |
---|---|
requestFullscreen(lockPointer, resizeCanvas) |
Same function added by the other Emscripten implementations (for backward compatibility purposes) |
glfwRequestFullscreen(target, lockPointer, resizeCanvas) |
The version specific to this implementation with the additional target argument (can be a canvas selector, a HTMLCanvasElement or a GLFWwindow ) |
glfwGetWindow(any) |
Returns the GLFWwindow pointer associated to the canvas (any can be a canvas selector or a HTMLCanvasElement ) |
glfwGetCanvas(any) |
Returns the canvas associated to the window (any can be a canvas selector or a GLFWwindow ) |
glfwGetCanvasSelector(any) |
Returns the canvas selector associated to the window (any can be a canvas selector or a GLFWwindow ) |
glfwMakeCanvasResizable(any, resizableSelector, handleSelector) |
Same functionality as MakeCanvasResizable (any can be a canvas selector or a GLFWwindow or a HTMLCanvasElement |
glfwUnmakeCanvasResizable(any) |
To revert Module.glfwMakeCanvasResizable |
glfwIsRuntimePlatformApple() |
To check if the platform is Apple (ex: for keyboard shortcuts) |
In addition, this implementation will check if the function Module.glfwOnWindowCreated(glfwWindow, selector)
is
defined in which case it will be called once the window is created. This allows writing code like this:
Module = {
// ...
glfwOnWindowCreated: (glfwWindow, selector) => {
if(selector === '#canvas2') {
Module.glfwMakeCanvasResizable(glfwWindow, '#canvas2-container');
}
},
// ...
};
This implementation being in C++ and implementing far more features than the library_glfw.js
Emscripten
implementation, it has an impact on size.
As of initial release, I ran the following experiment on both implementations using example_minimal
Mode | library_glfw.js |
This implementation | Delta |
---|---|---|---|
Debug | js: 170775, wasm: 75789, total: 246564 | js: 99559, wasm: 4492007, total: 4591566 | 18.8x |
Release | js: 135433, wasm: 8448, total: 143881 | js: 81285, wasm: 80506, total: 161791 | 1.12x |
Release (minimal) | - | js: 79402, wasm: 71195, total: 150197 | 1.04x |
- From these numbers, and for obvious reasons, there is more wasm code than JavaScript code in this implementation (which is a good thing).
- Although the size is pretty terrible in
Debug
mode (almost a 19x size increase), inRelease
mode it is actually only a 12% increase which shows that wasm optimizes quite well :) - The last entry in the table shows the same results when compiling with all disable options turned on
(
EMSCRIPTEN_GLFW3_DISABLE_JOYSTICK
,EMSCRIPTEN_GLFW3_DISABLE_MULTI_WINDOW_SUPPORT
andEMSCRIPTEN_GLFW3_DISABLE_WARNING
) for an even smaller footprint - Lastly,
.wasm
files compress extremely well, so it is worth serving them compressed
> cd examples/example_minimal
# using library_glfw.js
> emcc -sUSE_GLFW=3 main.cpp -O2 -o /tmp/build/index.html
# using contrib.glfw3
> emcc --use-port=contrib.glfw3 main.cpp -O2 -o /tmp/build/index.html
# using contrib.glfw3 (minimal)
> emcc --use-port=contrib.glfw3:disableWarning=true:disableJoystick=true:disableMultiWindow=true main.cpp -O2 -o /tmp/build/index.html
Mode | library_glfw.js |
This implementation | Delta |
---|---|---|---|
Release | js: 103908, wasm: 13903, total: 117811 | js: 59019, wasm: 73839, total: 132858 | 1.13x |
Release (minimal) | - | js: 56795, wasm: 66456, total: 123251 | 1.04x |
Note
The good news is that Emscripten is improving and this implementation is benefitting from it.
This table contains the list of all the GLFW functions API and whether they are supported by this implementation (and the built-in implementation) with a few relevant notes
Note
GLFW 3.4 introduced the concept of a platform. This implementation adds the GLFW_PLATFORM_EMSCRIPTEN
define
in empscriptem-glfw3.h
: the value is reserved (in a comment), but it is not defined in glfw3.h
.
Function | emscripten-glfw (this implementation) |
library_glfw.js (built-in implementation) |
---|---|---|
glfwCreateCursor | Custom cursors are supported | |
glfwCreateStandardCursor | All GLFW cursors are supported: uses the CSS style cursor on the canvas |
|
glfwCreateWindow | Support as many windows as you want: see the section describing the association of a window and a canvas | Support only a single window |
glfwDefaultWindowHints | ||
glfwDestroyCursor | ||
glfwDestroyWindow | Reverts all changes (event listeners, CSS style, ...) set by this library | |
glfwExtensionSupported | Same implementation as library_glfw.js |
|
glfwFocusWindow | Calls JavaScript HTMLElement.focus() on the canvas |
|
glfwGetClipboardString | See the Clipboard Support section | |
glfwGetCurrentContext | Only available if glfwMakeContextCurrent was called previously |
|
glfwGetCursorPos | Hi DPI aware | |
glfwGetError | 3.3.x+ | |
glfwGetFramebufferSize | Hi DPI aware | Hi DPI aware |
glfwGetGammaRamp | (no access from JavaScript) | |
glfwGetGamepadName | If gamepad, corresponds to Gamepad.id in JavaScript |
3.3.x+ |
glfwGetGamepadState | If gamepad, then Gamepad.axes and Gamepad.buttons (js) remapped for GLFW |
3.3.x+ |
glfwGetInputMode | Supports only GLFW_CURSOR , GLFW_STICKY_KEYS and GLFW_STICKY_MOUSE_BUTTONS |
Supports only GLFW_CURSOR |
glfwGetJoystickAxes | Corresponds to Gamepad.axes in JavaScript |
|
glfwGetJoystickButtons | Corresponds to Gamepad.buttons[x].value in JavaScript |
|
glfwGetJoystickGUID | Corresponds to Gamepad.mapping in JavaScript |
|
glfwGetJoystickHats | If gamepad, corresponds to Gamepad.buttons[x].pressed in JavaScript remapped for GLFW |
|
glfwGetJoystickName | Corresponds to Gamepad.id in JavaScript (limited to 64 characters due to Emscripten limitation) |
|
glfwGetJoystickUserPointer | ||
glfwGetKey | Support GLFW_STICKY_KEYS as well |
No sticky support / Broken Meta Key |
glfwGetKeyName | All names start with DOM_PK_ : example, DOM_PK_F1 . |
|
glfwGetKeyScancode | See KeyboardMapping.h for actual mapping |
|
glfwGetMonitorContentScale | Corresponds to window.devicePixelRatio in JavaScript |
|
glfwGetMonitorName | The constant "Browser" | The constant "HTML5 WebGL Canvas" |
glfwGetMonitorPos | Always 0/0 | Always 0/0 |
glfwGetMonitorPhysicalSize | (no access from JavaScript) | |
glfwGetMonitors | Due to JavaScript restrictions, always only 1 monitor | 1 monitor |
glfwGetMonitorUserPointer | 3.3.x+ | |
glfwGetMonitorWorkarea | 0x0 for position, screen.width xscreen.height for size |
0x0 for position, screen.availWidth xscreen.availHeight for size |
glfwGetMouseButton | Support GLFW_STICKY_MOUSE_BUTTONS as well |
No sticky mouse button support |
glfwGetPlatform | GLFW_PLATFORM_EMSCRIPTEN (see note above) |
3.4.x+ |
glfwGetPrimaryMonitor | The single monitor returned in glfwGetMonitors |
Same |
glfwGetProcAddress | Implemented by Emscripten GL | Implemented by Emscripten GL |
glfwGetRequiredInstanceExtensions | ||
glfwGetTime | ||
glfwGetTimerFrequency | Always 1000 | |
glfwGetTimerValue | Corresponds to performance.now() in JavaScript |
|
glfwGetVersion | 3.2.1 | |
glfwGetVersionString | "Emscripten/WebAssembly GLFW " + GLFW version | "3.2.1 JS WebGL Emscripten" |
glfwGetVideoMode | ||
glfwGetVideoModes | ||
glfwGetWindowAttrib | Supports for
|
GLFW_SCALE_TO_MONITOR only |
glfwGetWindowContentScale | If HiDPI aware (GLFW_SCALE_FRAMEBUFFER is GLFW_TRUE ), then current monitor scale, otherwise 1.0 |
Similar |
glfwGetWindowFrameSize | Because a window is a canvas in this implementation, there is no edge => all 0 | |
glfwGetWindowMonitor | The single monitor returned in glfwGetMonitors |
Same |
glfwGetWindowOpacity | Always 1.0 | |
glfwGetWindowPos | The position of the canvas in the page getBoundingClientRect(canvas).x&y |
Whatever was set in glfwSetWindowPos , so not the actual position |
glfwGetWindowSize | The size of the window/canvas | Same |
glfwGetWindowTitle | The title of the window/canvas | 3.4.x |
glfwGetWindowUserPointer | ||
glfwHideWindow | Set CSS property to display: none for the canvas |
|
glfwIconifyWindow | ||
glfwInit | Set a listener to monitor content scale change (ex: moving browser to different resolution screen) | |
glfwInitAllocator | (due to JavaScript, memory cannot be managed) | 3.4.x |
glfwInitHint | GLFW_PLATFORM with value GLFW_ANY_PLATFORM or GLFW_PLATFORM_EMSCRIPTEN |
3.3.x |
glfwJoystickIsGamepad | Returns GLFW_TRUE when the joystick mapping (Gamepad.mapping ) is "standard" |
|
glfwJoystickPresent | Listens to gamepadconnected and gamepaddisconnected events to determine the presence. |
|
glfwMakeContextCurrent | Since this implementation supports multiple windows, it is important to call this if using OpenGL | Since there is only 1 window, it does nothing |
glfwMaximizeWindow | ||
glfwPlatformSupported | GLFW_TRUE for GLFW_PLATFORM_EMSCRIPTEN only (see note above) |
3.4.x |
glfwPollEvents | Polls for joysticks only (can be disabled with disableJoystick=true port option or EMSCRIPTEN_GLFW3_DISABLE_JOYSTICK define) |
|
glfwPostEmptyEvent | ||
glfwRawMouseMotionSupported | Always GLFW_FALSE (not supported) |
Same |
glfwRequestWindowAttention | ||
glfwRestoreWindow | ||
glfwSetCharCallback | Uses KeyboardEvent.key to compute the proper codepoint. Note that `GLFW_MOD_CAPS_LOCK` and `GLFW_MOD_NUM_LOCK` are **not** supported |
|
glfwSetCharModsCallback | (deprecated in GLFW) | |
glfwSetClipboardString | Uses navigator.clipboard.writeText . See the Clipboard Support section. |
|
glfwSetCursor | Uses CSS style cursor: xxx for the canvas |
|
glfwSetCursorEnterCallback | Listeners to mouseenter and mouseleave events |
|
glfwSetCursorPos | (JavaScript does not allow the cursor to be positioned) | |
glfwSetCursorPosCallback | Hi DPI aware | |
glfwSetDropCallback | (JavaScript only gives access to filename, so it is pointless) | (Copies the entire file(s) in memory) |
glfwSetErrorCallback | This call stores the pointer but never uses it as this implementation is not handling errors compliantly | |
glfwSetFramebufferSizeCallback | Hi DPI aware | Same |
glfwSetGamma | ||
glfwSetGammaRamp | ||
glfwSetInputMode | Supports only GLFW_CURSOR , GLFW_STICKY_KEYS and GLFW_STICKY_MOUSE_BUTTONS |
Supports only GLFW_CURSOR |
glfwSetJoystickCallback | ||
glfwSetJoystickUserPointer | ||
glfwSetKeyCallback | ||
glfwSetMonitorCallback | Callback is never called | Same |
glfwSetMonitorUserPointer | 3.3.x | |
glfwSetMouseButtonCallback | ||
glfwSetScrollCallback | Listens to mousewheel events |
|
glfwSetTime | ||
glfwSetWindowAspectRatio | Only works if the user is controlling the canvas size (spec does not define one way or another) | |
glfwSetWindowAttrib | See glfwGetWindowAttrib |
See glfwGetWindowAttrib |
glfwSetWindowCloseCallback | There is no concept of "closing" a canvas | Called on window destroyed. |
glfwSetWindowContentScaleCallback | Callback only called if Hi DPI aware (GLFW_SCALE_FRAMEBUFFER is GLFW_TRUE ) |
Same |
glfwSetWindowFocusCallback | Callback pointer is stored but never used | |
glfwSetWindowIcon | (icon could be mapped to favicon but beyond 1.0 scope) | |
glfwSetWindowIconifyCallback | ||
glfwSetWindowMaximizeCallback | ||
glfwSetWindowMonitor | ||
glfwSetWindowOpacity | Uses CSS style opacity: xxx for the canvas |
|
glfwSetWindowPos | (there is no generic way to set a canvas position) | |
glfwSetWindowPosCallback | Uses top/left of the value returned by getBoundingClientRect(canvas) ) |
|
glfwSetWindowRefreshCallback | Returns callback provided: callback is never called | Callback stored but never called |
glfwSetWindowShouldClose | ||
glfwSetWindowSize | Hi DPI Aware: set the size of the canvas (canvas.width = size * scale ) + CSS style (style.width = size ) |
|
glfwSetWindowSizeCallback | ||
glfwSetWindowSizeLimits | Only works if the user is controlling the canvas size (spec does not define one way or another) | |
glfwSetWindowTitle | Corresponds to document.title in JavaScript |
|
glfwSetWindowUserPointer | ||
glfwShowWindow | Removes CSS style display: none for the canvas |
|
glfwSwapBuffers | ||
glfwSwapInterval | Uses emscripten_set_main_loop_timing |
Same |
glfwTerminate | Tries to properly clean up everything that was set during the course of the app (listeners, CSS styles, ...) | |
glfwUpdateGamepadMappings | 3.3.x | |
glfwWaitEvents | ||
glfwWaitEventsTimeout | ||
glfwVulkanSupported | Always return GLFW_FALSE |
Same |
glfwWindowHint |
|
Anything (no check on argument) |
glfwWindowHintString | ||
glfwWindowShouldClose |
Note
For non-supported functions, this library logs a warning the first time they are called (which can be disabled via
disableWarning=true
port option or EMSCRIPTEN_GLFW3_DISABLE_WARNING
define) and are doing nothing,
returning the most "sensible" value (like nullptr
) if there is an expected return value.
Calling any of these will not break the library.