fschutt/azul

How ready is this?

wbogocki opened this issue ยท 24 comments

I'm thinking of using this for work for a prototype of a thing. I'm wondering if Azul is ready enough to be used for things that may be used in a production-ish-like setting atm or if it's a heavy work in progress with no assurance of stability, incomplete features and all the rest that comes with growing up a project. Let me know how it is. Thanks!

I don't think it's ready yet, the 0.1 release is roughly in a month or two away. You can take a look at the 0.1 project board to see how far certain features are.

There are features that are missing, that I'd consider "necessary" for any non-hello-world app, that should be part:

(Updated 01-04-2019)

  • Tracking input focus (right now text fields can only be entered if the mouse cursor is hovering over them, because there is no "currently focused" text field). This also needs to track the focus across frames. Update: implemented, but no tab navigation for 0.1 release
  • Text selection and inline-block layout (to implement text cursors and document-like layout). Update: No text selection for 0.1, too complicated to handle. Only basic inline layout will be present.
  • Scrolling (implemented already, but disabled due to clipping problems)
    • Also needs a programmatic API to programatically scroll divs to a certain state
    • Needs to display scroll bars with overflowing elements, otherwise there's not much use in having scrollable elements if a user can't scroll them
    • Update: Scrolling will only be present for IFrames, overflow handling turned out to be very complicated (mostly due to the question on how to handle scrollbars and layout properly).
  • Multi-window handling
    • This is mostly a problem with OpenGL, since sharing one OpenGL context between multiple windows easily leads to segfaults
    • Needs a better API so that you can seamlessly transition between an absolute-positioned div and a new window
    • Update: Implemented, but won't get a seamless-window API for 0.1 release, just a basic API to create, destroy and route windows.
  • Drag & drop support like in HTML (with ondragstart, ondragend, etc.) - Update: Won't make it to 0.1 release, needs multi-window handling to work first
  • Mac & Wayland display issues (right now "cross platform" just means "Windows and X11") - Update: Mostly fixed, Mac & Wayland support is still wonky, but getting there.
  • Dependency issues and webrender bugs (webrender isn't on crates.io yet, webrender has known bugs related to gradients). - Update: Fixed by vendoring, shouldn't be a permanent solution

That's not to say that Azul isn't useful yet, but I wouldn't use it for a production app yet. Below is a screenshot of the application I'm currently programming using this framework, so I'm trying to verify that the programming model can scale to more complex apps:

23b00f1b05c22fd96f85036eefa40672e65e3b17

However, for example text fields currently just push and pop characters at the end of the string, since there is no "text cursor" yet - since I am writing the app for myself, that works fine, but for a production app, it would be a very bad user experience not to have a text cursor. And of course, this doesn't really scale to thousand-line documents, where you'd need different types of datastructures, not just a string.

So I'd expect the 0.1 version to be released in 1 - 2 months (i.e January / February 2019). I'll do a "release announcement", so you can "watch for releases only" on this repository if you want to be notified.

Alright, got it. I'll have a look again at that time then. Thanks.

Hm, I'd leave this open for now, because I get this question a lot - usually people don't take a look at the project board, only at the issues, so I'll leave this issue open until the 0.1 release, for better visibility.

OtaK commented

Hey, I'm also thinking of betting on azul (I already have a lot of experience with Conrod, but hey, I like Azul's design and underlying concepts, so I want to give it a try) for a production app, and I'd be super open to contribute back on the issues we'd fix. Would that be a thing for you or not?

@OtaK Well, the issues right now are fairly managable, the main problem is that they sort-of depend on each other. Ex. I can't implement drag & drop support without implementing multi-window handling first (because during the dragging, the element needs to be rendered in a seperate window, so it depends on multi-windowing). I can't re-enable scrolling without solving the clipping situation first, I can't publish parts of the API without solving dependencies in webrender first, etc.

And at least for now, I have lots of time to work on these internals - it's faster for me to implement these things on my own, rather than to coordinate PR merges. However, if you want to help: develop widgets (or at least try to)! For example, try creating:

  • a calendar widget
  • a slider
  • a checkbox
  • a tree view
  • a ListView
  • a dropdown menu

Take a look at the widgets/table_view.rs on how to structure these kinds of components. Or try:

  • fixing the table view to correctly select cells and allow input to the correct cells
  • using xml-rs to parse XML and output a DOM, as described here - useful to create GUI builders and hot-reloadable DOM elements later on
  • refactoring azul/layout.rs and text_layout.rs as well as widgets into their own crates

This would probably help more than trying to mess with internals (which currently break the API every 24 hours) - plus you'd learn how to use azul in the process. As it is right now, the 0.1 release would be done without any widgets (just releasing the "core" library, and widgets are then added in 0.2). But someone has to write standard widgets at some point, so that's something you could help me with.

OtaK commented

I guess before thinking of making full-fledged widgets, the elementary building-block views need to be made I think (eg: React Native's FlatView, addressing the common use case of long item lists that need to be only partially redrawn on scroll to save memory and CPU). Our project will have a completely custom UI so commonly-used widgets won't be much of use to us, building blocks will be much more useful.

That's a task I can afford to do since I'll do it anyway ยฏ_(ใƒ„)_/ยฏ

I'll start working on the said project at the beginning of January so I (or members of my team at @YellowInnovation) will be in touch here.

(eg: React Native's FlatView, addressing the common use case of long item lists that need to be only partially redrawn on scroll to save memory and CPU).

That already exists in azul, it's called an IFrameCallback. This is how the table demo is implemented (since tables are infinitely large, after all) - the callback gets called with the desired size (after layout is done), then the DOM can adjust itself to however large the desired size is.

So if you have 100000 elements, you can make an IFrameCallback, which will then be called with a size of let's say 100 x 200 px, then you can add event listeners to On::Scroll and calculate what items need to be rendered on the screen.

@fschutt It might be a good idea to open some issues with good first issue tags for newcomers. I think a lot of the Rust community is really interested in this project and could provide a lot of value, even with just simple tasks like adding new CSS property parsers. Sure, the inner workings aren't stable yet, but it takes time for a new contributor to get up to speed with the basics anyways.

More widgets essential for getting people to adopt. In particular I needed a dropdown and some checkboxes. My use case is managing a simple settings struct, basically a TOML editor, for getting something / anything in front of the user before trying to fire up Vulkan in case they need to manually switch something to get it to run.

@fschutt webrender is now on crates.io, are there additional things you need in that respect before publishing azul on crates? Or are you only blocked on other things?

@staktrace Well I need to finalize the API properly. This is why I'm writing an application alongside of this library, to fix API problems. And I need to solve problems with flickering, redrawing, the window not showing, etc. I wouldn't consider the library to be in a "usable" state when it still flickers like crazy. I've been mostly busy trying to solve the OpenGL situation, see the gl_rework branch for progress.

Currently the main thing blocking it is that the layout system is pretty broken (I refactored it to use stretch, but I broke the layout solver in the process), but it can work with a bit of manual width / height calculation. So I'd probably publish a 0.1 version with a broken layout solver. However, the text layout is in a much better state right now, compared to the master branch.

I'll probably un-vendor the libraries for a release. I know I said January, that was a bit early. But it's getting there.

A small update:

  • Multi-window handling is unlikely to make it until rust-windowing/glutin#1184 is fixed. Previously I tried it with older winit / glutin versions and just experienced segfaults and crashes.
  • Scrolling + programmatic scrolling (i.e. "scroll to end on click") is implemented, but not properly documented.
  • Layout is still a problem, especially inline text layout. The core algorithms are done, just the actual layout is a problem, also needs better documentation. It's likely that the first version will either be done without stretch.
  • The idea was to port azul-core to WASM (since azul-core has no / few external dependencies), so that eventually azul can run on both web and desktop natively (on the web, it just uses the regular flex algorithm from the web browser). Then it would be easy to write an azul-web crate that simply renderst the Azul DOM tree into a HTML DOM tree and hands it to the browser (no canvas / WebGL necessary like in Qt for example, everything done via "web-native" HTML + CSS which Azul already supports). This is also a reason why I picked a "DOM / CSS" approach.

@fschutt Would you be willing to provide another "State-of-the-Project" address here?

See this:

https://www.reddit.com/r/rust/comments/c24b57/azul_the_gui_framework_will_be_unmaintained_from/

For alternatives check out https://areweguiyet.com/

Among the actively maintained GUI projects, I think the one most closely resembling Azul (in spirit) is Tauri, since it also enables apps to be developed with standard browser tech.

rask commented

I'm seeing activity in the repo, so not unmaintained anymore?

@rask Yes, but there are still lots of bugs that need to be resolved before a release. I'm building my application in parallel to this repository in order to test azul in practice, so once my application works without major bugs, I can release it.

The 1.0.0-alpha1 version has been released, but it's Windows-only for now: https://github.com/fschutt/azul/releases/tag/1.0.0-alpha1

How hard would it be to make it work on Linux? (i.e. how much platform-specific code is there?)

@jplatte There are only two platform-specific functions (App::get_monitors and App::run). There are about ~2000 lines of platform specific code, see https://github.com/fschutt/azul/blob/master/azul-desktop/src/shell/other.rs, compared with https://github.com/fschutt/azul/blob/master/azul-desktop/src/shell/win32.rs

And the https://github.com/fschutt/azul/blob/master/azul-desktop/src/window.rs file uses winit currently, which has to be adjusted.

The main platform-specific code relates to:

  • initializing / synchronizing the window state and cursor
  • handling resize, draw, mouse input and keyboard input events
  • loading OpenGL function pointers to initialize the OpenGL context (wglGetProcAddress on Windows, eglGetProcAddress on Linux)
  • integrating with system timers (i.e. WM_TIMER) for running animations, timers and threads
  • optional platform-specific context and window menus (WM_COMMAND), accessibility (WM_GETOBJECT) and borderless window drawing (WM_NCHITTEST)

See

struct Window {
/// HWND handle of the plaform window
hwnd: HWND,
/// See azul-core, stores the entire UI (DOM, CSS styles, layout results, etc.)
internal: WindowInternal,
/// OpenGL context handle - None if running in software mode
gl_context: Option<HGLRC>,
/// OpenGL functions for faster rendering
gl_functions: GlFunctions,
/// OpenGL context pointer with compiled SVG and FXAA shaders
gl_context_ptr: OptionGlContextPtr,
/// Main render API that can be used to register and un-register fonts and images
render_api: WrRenderApi,
/// WebRender renderer implementation (software or hardware)
renderer: Option<WrRenderer>,
/// Hit-tester, lazily initialized and updated every time the display list changes layout
hit_tester: AsyncHitTester,
/// ID -> Callback map for the window menu (default: empty map)
menu_callbacks: BTreeMap<u16, MenuCallback>,
/// Timer ID -> Win32 timer map
timers: BTreeMap<TimerId, TIMERPTR>,
/// If threads is non-empty, the window will receive a WM_TIMER every 16ms
thread_timer_running: Option<TIMERPTR>,
/// Hash of the current system menu
menu_hash: Option<u64>,
/// characters are combined via two following wparam messages
high_surrogate: Option<u16>,
}
for a start - the main code is cross-platform, handled in the cross-platform WindowInternal class.

I only re-implemented Windows because winit had a lot of state synchronization and redrawing bugs regarding WM_PAINT. But it doesn't yet work perfectly on Windows, so I'm waiting with porting it to Linux.

Winit cannot draw transparent OpenGL windows, something which I've experimented with. See https://gist.github.com/je-so/903479 on how to initialize an X11 ARGB window (that's why I want to re-implement X11 manually).

For Linux I will only target X11 for now because Wayland has bugs with showing the application properly (see #190).

For Linux I will only target X11 for now

Oh, that is very unfortunate. Then again if you want to bypass winit for X11 that might actually be good for the project I'd like to do with azulยน since it would benefit from the Wayland support also bypassing winit and using a more flexible, lower-level crate like smithay-client-toolkit.

ยน a status bar for wayland compositors similar to Waybar

I'm not opposed to supporting Wayland, but it has to work on X11 first. All of the Wayland bugs can be solved by just running Azul under XWayland, so at least for now it's a solution. Azul technically just needs a window + an OpenGL framebuffer: it can't be that hard to port that to Wayland. But often people report bugs for Wayland here and I can't do anything about it because I have to wait for winits development to fix the bugs, then wait for winit to release a new version, then undo all of the unnecessary stuff winit adds and then hope that it works. So that's also why I'd like to have control over the platform-specific code myself, it's way easier to debug.

Then there are things that winit intentionally doesn't support such as integrating client-side decorations (to let window decorations been drawn by webrender), transparent windows, menu handling (has to be implemented via floating / tear-off "menu windows" - Linux is the only platform that doesn't have a concept of "native" menus like Windows / macOS) and per-monitor DPI changes.

winit already uses sctk internally to draw decorations - which is something I don't like because the window decorations do not look like the system style. I think KDE has some special Wayland protocols to force server-side decorations. Otherwise you'd also need to somehow fetch the system style so that your app looks "native".

Wayland is especially a lot of work because it doesn't even draw window decorations (such as minimize / maximize / close buttons). So the toolkit has to implement that, too. It's just a lot more work to implement that X11.

All of the Wayland bugs can be solved by just running Azul under XWayland, so at least for now it's a solution.

For my use case I'm pretty sure XWayland is not an option because the rendering wouldn't happen inside a regular window with decorations and such, it would happen in a special kind of surface that is given a fixed part of the screen and doesn't participate in the regular windowing mechanisms. I don't think XWayland can do anything other than regular windows or fullscreen.

But I totally get your point. I just hope that the heroes from @Smithay will make native Wayland support in Azul a reality (or help a noob in this area such as myself to do it). Luckily I don't seem to be the only person interested in that, based on the fact that one of the guys also working on Smithay previously wrote a small patch to improve Wayland support (#116).

@jplatte It does run on Linux via winit already:

winit

However, one of the problems that I only noticed on win32 is that I was drawing to the screen before the frame was "ready" to be built. I split the azul-desktop crate into "Windows" (using raw Win32) and "everything else" (using winit). The winit code is already there, but there are a few compilation errors that would need to be fixed.

I am currently only focused on Win32, because that's where I have to run my application (I use Adobe products, I sadly can't switch everything to Linux yet). You can leverage the existing cross-platformness of winit already, but it's just not 100% perfect, especially with regards to respecting system-native theming.

I am currently only focused on Win32, because that's where I have to run my application

This is fine. See libui allowing common functionality - but past that point you can not do
much. I think if the underlying code base is written with a "try to be platform agnostic",
even if you focus on win, in the long run it may well be ported / portable to other
platforms or these bindings lateron becoming better. Just document limitations, people
can adapt and work around.

The original issue has been created ~3 years ago.

It would be interesting to see how much progress was made in the last 3 years,
and how the support for azul may become better in the coming 3 years.

The xorg-versus-xwayland is mostly "bike shedding" IMO. The more important
focus should be on either variant for azul to be usable. Or do linux users fail
to use xorg or xwayland? Why could they not easily transition? For the record
I use xorg so I don't really even care about wayland; I just wonder about those
folks who say "omg omg omg only wayland or it does not exist omg omg omg".