Skip to content

Instantly share code, notes, and snippets.

View adamjs's full-sized avatar
🤠
Wranglin' code

Adam Simmons adamjs

🤠
Wranglin' code
View GitHub Profile

Exposing Qt Classes to JavaScriptCore: A Dynamic Proxy Approach with Signal Support

When working with Ultralight, you may want to expose your C++ classes to JavaScript. If your C++ application is based on Qt, you may find yourself in the challenging position of exposing a vast number of Qt classes to JavaScript, which could involve writing tedious manual bindings for each class. However, using Qt's meta-object system (reflection), you can dynamically expose these classes with far less effort.

In this article, we'll walk through how to set up a dynamic proxy using the JSC C API and Qt's meta-object system. This proxy will automatically forward method calls and property accesses in JavaScript to the corresponding Qt object in C++, and also support Qt's signal-slot mechanism.

Overview of the Proxy Approach

Instead of manually defining JavaScript bindings for every Qt class and method, we create a generic proxy. This proxy will:

  1. Intercept method calls and property accesses made on
@adamjs
adamjs / win_crash_dmp_logger.cpp
Created August 6, 2024 21:23
Utility code to log crashes to .dmp files on Windows for remote debugging
#include <windows.h>
#include <dbghelp.h>
#include <iostream>
#include <strsafe.h>
// Link with the DbgHelp.lib
#pragma comment(lib, "dbghelp.lib")
// Function to create the dump file
void CreateDump(EXCEPTION_POINTERS* pExceptionPointers, TCHAR* szFileName)
@adamjs
adamjs / d3d9_texture_streaming.md
Created December 5, 2023 02:14
D3D9 Texture Streaming

In Direct3D 9, you can upload pixels to a dynamic texture via the following:

  1. Create the Texture: In D3D9 you can create the texture using the CreateTexture method. Make sure to specify the D3DUSAGE_DYNAMIC flag in the Usage parameter.

    IDirect3DTexture9* pDynamicTexture = NULL;
    HRESULT hr = pDevice->CreateTexture(width, height, 1, D3DUSAGE_DYNAMIC, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &pDynamicTexture, NULL);
@adamjs
adamjs / mouse_input_UL-1-3.md
Last active October 16, 2023 23:52
Mouse Input in Ultralight (1.3 API)

Sending Mouse Input to a View

To send mouse input to a View, you should first create a MouseEvent and then pass it to the function View::FireMouseEvent.

Mouse Move Event

You should send a Mouse Move event whenever the mouse changes position.

Here is an example of moving the mouse to (100, 100) coordinate with no buttons pressed:

//
// Assume you had some DOM element on your page with id == 'placeholder', for example:
//
// <html>
// <body>
// <div id='placeholder'></div>
// </body>
// </html>
//
// We can bind a custom function to a JSObjectRef in C to query it's location natively.
@adamjs
adamjs / MyApp.cpp
Last active January 16, 2020 22:48
Async callback example using JavaScript Promises (Ultralight 1.1)
#include "MyApp.h"
#include <chrono>
#include <thread>
#define WINDOW_WIDTH 600
#define WINDOW_HEIGHT 400
const char* htmlString();
MyApp::MyApp() {
@adamjs
adamjs / select_example.html
Created January 4, 2020 18:41
Example of using JavaScript/CSS to render <select> elements in Ultralight.
<!-- This is an example of using themeable JavaScript replacements to style
<select> elements in Ultralight.
-->
<html>
<head>
<link href="https://unpkg.com/mobius1-selectr@latest/dist/selectr.min.css"
rel="stylesheet" type="text/css">
<script src="https://unpkg.com/mobius1-selectr@latest/dist/selectr.min.js"
type="text/javascript"></script>
<style>
@adamjs
adamjs / promises_test.cpp
Created December 3, 2019 06:50
Testing JavaScript Promises with Ultralight 1.1
#include <AppCore/App.h>
#include <AppCore/Window.h>
#include <AppCore/Overlay.h>
#include <AppCore/JSHelpers.h>
using namespace ultralight;
const char* htmlString();
class MyApp : public LoadListener {
// Inside Tab.cpp, replace your void Tab::OnAddConsoleMessage definition with all of the following:
inline std::string ToUTF8(const String& str) {
String8 utf8 = str.utf8();
return std::string(utf8.data(), utf8.length());
}
inline const char* Stringify(MessageSource source) {
switch(source) {
case kMessageSource_XML: return "XML";
@adamjs
adamjs / CAPI.h
Created February 1, 2019 22:13
Draft C API for Ultralight
#ifndef ULTRALIGHT_CAPI_H
#define ULTRALIGHT_CAPI_H
#ifndef __cplusplus
#include <stdbool.h>
#endif
#include <stddef.h>
#include <uchar.h>
#include <JavaScriptCore/JavaScript.h>