HTML UI
Hyper Text Markup Language User Interface
Library aiming to deliver simple API for building apps with HTML
+CSS
+JS
UI in C
/C++
/Python
and thus make developing GUI app as easy as it can be.
You will be not limited to desktop apps - HTTP backend lets you to do anything from desktop app to web app with one API (comming soon; see limitations).
Currently Linux and Windows are supported (more comming soon).
I'm aware that the code quality is not the best however it mostly works plus it's up to you whether you decide to use it.
I propose idea of having custom user settings for all HTML UIs - having custom *.css
and *.js
file that gets always loaded (and doesnt mess up anything else).
This would be great not only for apps using HTML but also for web pages (only there would be issue that we are used to their visual signature that can protect us from fake sites).
This not only it will looks nice from users perspective, but it will also be much easier to develop nice UI (and thus cost effective and/or less time consuming).
current status:
Default theme is in HUI_theme.css
and is included within builds (additionally some more tweaks are loaded too).
To apply custom theme, you can use CSS and create custom stylesheet and save it to $HOME/.config/HUI_theme.css
or %userprofile%/HUI_theme.css
(just try to not break the layout; you should implement the .hui_unstyled
class as in the default theme).
For simplicity, all other settings (like language, platform-specific options, ...) are also included in theme file as CSS variables. (Consult the hui_theme.css
for more info.)
This time the code is the documentation - look into the code - HUI.h
and HUI.hh
should give you some ideas on how it works.
I decided to stick with the simplest tools.
Linux or MinGW g++
(C++):
cd build
g++ -o <binary> ../<source> -I../../HUI -L. -lHUI
Linux or MinGW gcc
(C):
cd build
gcc -o <binary> ../<source> -I../../HUI -L. -lHUI
Windows MSVC cl.exe
(C++):
cd build
cl /EHsc /Fe:<binary>.exe ../<source> /I../../HUI /link /LIBPATH:. libHUI.lib
Windows MSVC cl.exe
(C):
cd build
cl /Fe:<binary>.exe ../<source> /I../../HUI /link /LIBPATH:. libHUI.lib
Rust (first, copy your project into HUI root):
cd <your project>
cargo build --release
(All examples assume that HUI repo and app repo directories share the same directory. And that build
directory already exists and contains libHUI.so
or libHUI.dll + libHUI.lib
)
It is also possible to use HUI as header-only library (just include the backend file hui_*.cc
before including HUI.hh
) - then you have to link to libraries that libHUI links to (generally, you just modify the command that is used to build libHUI to build binary and add libraries you use).
The recommended way is to use build scripts (files that start with build_
).
Build scripts can also serve as documentation for the build process (I really recommend reading them before running them).
To start build, run: \
build_<backend>.{sh,bat,py} [--dependencies] [--deploy] [--tests]
Python module is build just like any other app using HUI (except that here you build dynamic library instead of binary).
The bindings are defined in hui_python.cc
and use pybind11.
First, you have to build libHUI (you can use dummy build as template for linking, provided that you used same compiler), then run build_python.py
(again, this file can serve as documentation).
HUI 'newnew' - attempt to reimplement HUI from beginning
(few things are yet to be done to have usefull library - styling, bugs, hui init, content loading, js api)
BACKEND | STATUS | OS | NOTES |
---|---|---|---|
WebKit (GTK3) | working | Linux (x86_64, arm64, armhf) | ok |
Blink (CEF) | working, buggy | Windows (AMD64) | GPU acceleration disabled (causes crashes); transparency not working |
Webkit (Qt5) | working, deprecated | Windows, Linux | uses old HTML/CSS/JS |
none (dummy) | working | all |
- [api] backend_name/window_type (x11, wayland)
- [api] load_uri, load_str, load_file (path enhancements?)
- [build] rename hui_cpp_to_c_helper.hh to hui.cc + handle platforms/multiplatform here (may need to redo build scripts) + put things into directories + ?using namespace :: in those files
- [api] support layer-shell again -- init? / defered part of constructor -> solves "before show" and "before creation"
- [api] clean exit -> exit()
- [build] debug control, python bindings flag, handle hui.js and hui.css as define/text replace (so we dont need quoting)
- [api] callbacks for window close
- [tests] tests: async js, window ctls, load_*
- [new_backend] rust http server (something between desktop app and web app) + url or browser in kiosk mode https://superuser.com/questions/716426/running-latest-chrome-for-windows-in-kiosk-mode
- [api: cpp] fix copy/move constructor issues with HUI::WebView()
- [api] reconsider window.show/realize
- [api] callbacks for window controls
- [tweaks] get rid of private js and css (if possible and if safe)
- [api, js_api] put sent2cpp_handlers into impl (if possible) or get rid of them; do: js calls cpp -> cpp calls one function that handles callbacks on the api/abi level
- [api] inheritance for backend implementations (and maybe namespaces for backends -> multi-backend); methods: call_native, call_js/call_js_async, html_element
- [api, js_api] more native and faster 'html_element'/js api
- [js_api] expose whole api to js (just set of callbacks from js)
- [new_backend] cef linux
- [tweaks, controls] support client-side decorations trough user styling/scripting + select/get decoration scheme
- [tweaks] auto update theme (not sure about the js) -- maybe it can be just autorefresh implemented in js for loading stylesheet from custom app:// protocol
- [js_api] return from callback
- [new_backend] consider more backends, even proprietary https://ultralig.ht https://docs.rs/sciter-rs/latest/sciter/ (sciter is probably not compatible with html5/css3)
- [new_backend] update Qt backend with all Qt webViews availible (WebKit, CefView, MozEmbed, Ultralight, ...) - https://github.com/niutech/qt-ultralight-browser?tab=readme-ov-file -- this seems to be the easiest way to support the most backends
- [tweaks] (BIG PLAN) allow dynamically changed themes per screen/app/schedule *.css (may be done trough external tool and storage unshare -> HUI wayfire tool ~ but how to multiwindow?) --- per screen themes (TODO: need to be able to have two themes aplied side by side when shown on more than one monitor ~ switch themes quickly and stop updating the other area of the window)
- [api] threaded/multiprocess message loop (will need to figure out a way to return thread to c api) + thread-safety (the easiest solution seems to be creating optional thread safe wrapper running everything in external thread and handling the communication)
- [api] (BIG PLAN) upgrade API to serve as fully-featured and platform/renderer-agnostic base for building web browser (browser-beta)
- [new_backend] console backends: Cuervo (https://servo.org/made-with/#), the terminal browser project with chromium, old console browsers with js support
- [building] single master build script for everything + make it possible to combine windowcontrols/webview/windowembeder in different languages at linkage time
-
add concept of app - name, icon, ... => app property: void set_taskbar_icon(icon, name) + app.add(HUI::Window)
-
controls: callbackes(on_closing vs. on_closed ?)
-
add back windows controls; controls can have dual handles - backend + handle - or there may be 2 types of controls (toolkit + os) == window handle X backend pointer X c api pointer
-
WindowEmbeder (?): fix: black space when resizing -> two options = black artifacts and instant resize OR little laggy resize but no artifacts; [window embeding (see win implementation and wayland notes in old readme)]
-
window controls: parent/child windows (see old readme); popup windows (likely just prepared regular window; positioning and window type is yet to be discussed especialy for wayland)
-
wayland controls: https://wayland.app/protocols/xdg-shell
-
support MacOS - should work but untested + missing build scripts https://ports.macports.org/port/webkit2-gtk/details/
-
new backend: rust HTTP backend (something between desktop app and web app => "server mode" - app can run on headless server; prints out ui url / opens browser in kiosk mode ~ can work with with wrapper to get window id to control it) ~ multiuser: configurable action when user tries to connect existing instance (new app instance OR nothing; should be per app or per backend configurable?)
-
new backend: gtk4 rust webkit
-
check for memory leaks - install valgrind https://valgrind.org/docs/manual/quick-start.html#quick-start.intro https://valgrind.org/downloads/current.html https://valgrind.org/docs/manual/dist.readme.html
-
support drag and drop and copy/paste for text, files, images, application-specific (=allow real paths + predefined callbacks)
-
have option to run like regular webview -> rethink the automatic running of
hui_tweaks()
-
upgrade build scripts (error handling, bindings, packaging, colors) -> multibuild script calling the other scripts
-
refine purpose of hui.js/hui.css/theme file (fr scale + colors + elements) -- complete user styling and settings (1 css file)
-
unify js helper names across all platforms + create js API (should offer 2 options sync and async)
-
store native callbacks so that we can skip the C++ to C to C++ (maybe - seems to be complicated in respect to its benefits) -- will be likely better than the hell when converting the callbacks from one language to another
-
?better api (or just leave it for now): load_uri ;;; (string map based settings -- browser specific -- similar to flags) ;;; call_native handled by lang bindings -> simpler, easier, safer (but more complicated) -- make the call_native() be handled by the language bindings (issue with c->cpp, c only, header-only)
-
run without window manager - see notes in old readme (its better to include tiny wl compositor ~ so maybe nothing has to be done here)
-
allow moving running app from one browser to another (restore html and js context) -- without action from dev code (CANT BE THAT HARD - serialize all js including functions + .outerHTML)
-
(BIG PLAN) display server in browser (replacement for x11 and wayland -- when launched in browser in kiosk mode as fullscreenm) - relatively easy + can pair with greenfield (html wayland compositor -> support for legacy/direct drawing)
-
add popup (any popup ~ popups are not currently supported) that can exist outside the window (may be good idea to prepare the popup window)
-
create master build script that calls others + build scripts directory + release naming ( HUI-{platform}-{backend}{version or commit hash}{more info} )
-
research existing projects/ideas that can be used within this project
- [api] C++ api wrappers likely contain memory leaks (losing reference) + copy/move is not properly handled
- [backend gtk3] WEBKIT_DISABLE_COMPOSITING_MODE=1 + the transparency became random (vbox + 3d disabled; 3d enabled is buggy); similar: tauri-apps/tauri#8254
- [backend gtk3] hover effect doesnt reset when mouse exits window at the same time as exiting window
- [backend gtk3] window_handle returns pointer to wl_surface (better option should be considered ~ XDG-foreign if it will work for what we want)
- [tests] test if call_js return works for multiple statements
- [backend cef] calling destructor of webview causes crash instead of just closing the window
- [backend cef] window doesnt close when it goes out of scope
- keep everything simple
- dont change things that do work
- WebView, WindowControls, WindowEmbedder should be designed and developed independently - merging these can be done externaly (inheritance/member) and we can keep the API modular (old version can be kept while introducing new one)
- with any new API design, start with C
- provide build scripts and docs
- naming convension:
hui_*
- backend code,HUI*
- API code - every script should be ran from repo root = all commands should start and end in root of repo
- readme should go from less developer to more developer (from project about over api docs to developement informations; "end user", "app developer = library user", "library developer")
- readme should be only one, otherwise its a mess