An update, already done some of this, the conversion to std:: string in the C++ bindings is complete. The initial version of calling into native code from javascript in the embedded HTML widget is done, subject to change after input from the community.
This post is basically about my thoughts on stabilizing the Android version. There are two problems with the Android version currenty, stability and performance. I think both are important but stability is MORE important. To that end, I have an idea for a feature that will improve Android stability at the expense of some performance.
This is related to the DW_SIGNAL_EXPOSE which is the signal that is generated when a widget (generally a render widget) is ready to draw. This is the most dangerous area of code for an Dynamic Windows Android application. Calling any functions that might block can cause app hangs or use some extremely hacky code in Dynamic Windows that I wrote to get things to work, but is really dangerous and can lead to instability.
A history of widget drawing is required. When I started writing Dynamic Windows, when I started this project I supported OS/2, GTK1/X11 and Windows. All three of these platforms allowed drawing onto any widget, not just render widgets and at any time. Later I added Mac as a supported platform, and at that time also allowed drawing to any widget at any time. So this is how Dynamic Windows worked everywhere.
As time went on, drawing became more complex, and more restrictions were put in place. Some being unintentional, depending on the rendering system on the platform, and some were absolutely intentional. For instance any applications running via Wayland cannot draw outside of the draw event, so GTK3 using Wayland cannot draw outside of the EXPOSE event, and not arbitrarily onto any widget. GTK4 has these requirements regardless of the backend, even GTK4 via X11 which technically could do it, are restricted. The mobile platforms I recently added both also have similar restrictions, iOS requires drawing in the expose event as well. Android requires it and due to the way the message loop (Looper class) works it is dangerous to block in those callbacks.
For backward compatibility I have left in the ability to draw onto non-render widgets and at any time for the platforms that still support it, however this silently fails on platforms it doesn't work on. So my idea for the next version, is a feature toggle that will allow you to disable that backwards compatibility.
This feature would enforce drawing restrictions on platforms that could technically draw in situations that won't work on newer platforms that have those restrictions. Also on Android it would toggle the ability to draw in the callback directly. So the default on Android would be the "safe" mode which basically cache the EXPOSE event, create a pixmap from the widget and shunt it onto the safe Dynamic Windows thread where most events are handled. So the EXPOSE handler would not be running on the Android UI thread at all. When the EXPOSE handler returns, it will call back into the Android UI thread, trigger a draw callback and copy the modified pixmap. This might hurt performance since drawing might be delayed slightly, unlike currently it draws immediately and it needs to redraw the entire widget each time. However it will remove the ability to call the unsafe code to break out of the message loop.
Initially I would just implement it on Android and have the feature unsupported on other platforms. Then over time when I can get around to it, I'll add it to older platforms that it can be useful to restrict drawing so they function like the newer platforms.
Any thoughts?
This post is basically about my thoughts on stabilizing the Android version. There are two problems with the Android version currenty, stability and performance. I think both are important but stability is MORE important. To that end, I have an idea for a feature that will improve Android stability at the expense of some performance.
This is related to the DW_SIGNAL_EXPOSE which is the signal that is generated when a widget (generally a render widget) is ready to draw. This is the most dangerous area of code for an Dynamic Windows Android application. Calling any functions that might block can cause app hangs or use some extremely hacky code in Dynamic Windows that I wrote to get things to work, but is really dangerous and can lead to instability.
A history of widget drawing is required. When I started writing Dynamic Windows, when I started this project I supported OS/2, GTK1/X11 and Windows. All three of these platforms allowed drawing onto any widget, not just render widgets and at any time. Later I added Mac as a supported platform, and at that time also allowed drawing to any widget at any time. So this is how Dynamic Windows worked everywhere.
As time went on, drawing became more complex, and more restrictions were put in place. Some being unintentional, depending on the rendering system on the platform, and some were absolutely intentional. For instance any applications running via Wayland cannot draw outside of the draw event, so GTK3 using Wayland cannot draw outside of the EXPOSE event, and not arbitrarily onto any widget. GTK4 has these requirements regardless of the backend, even GTK4 via X11 which technically could do it, are restricted. The mobile platforms I recently added both also have similar restrictions, iOS requires drawing in the expose event as well. Android requires it and due to the way the message loop (Looper class) works it is dangerous to block in those callbacks.
For backward compatibility I have left in the ability to draw onto non-render widgets and at any time for the platforms that still support it, however this silently fails on platforms it doesn't work on. So my idea for the next version, is a feature toggle that will allow you to disable that backwards compatibility.
This feature would enforce drawing restrictions on platforms that could technically draw in situations that won't work on newer platforms that have those restrictions. Also on Android it would toggle the ability to draw in the callback directly. So the default on Android would be the "safe" mode which basically cache the EXPOSE event, create a pixmap from the widget and shunt it onto the safe Dynamic Windows thread where most events are handled. So the EXPOSE handler would not be running on the Android UI thread at all. When the EXPOSE handler returns, it will call back into the Android UI thread, trigger a draw callback and copy the modified pixmap. This might hurt performance since drawing might be delayed slightly, unlike currently it draws immediately and it needs to redraw the entire widget each time. However it will remove the ability to call the unsafe code to break out of the message loop.
Initially I would just implement it on Android and have the feature unsupported on other platforms. Then over time when I can get around to it, I'll add it to older platforms that it can be useful to restrict drawing so they function like the newer platforms.
Any thoughts?