New in version 1.3.0

Released 6 months ago

Please remember to uno clean your projects after upgrading Fuse.


  • You can now create UX classes inside Fuse Studio.
  • Faster preview refreshing of large apps on-device
  • A ton of performance optimizations and bug fixes in Fuse libs. (Including one nasty one which caused issues with Android 8).
  • Android release builds should be much smaller now.
  • New features to allow better navigation control from UX markup.



Note: On macOS, the ID of the Fuse application has changed, and you will get a popup from macOS saying: «Fuse Studio wants to use your confidential information stored in "Fuse Pro - Token" in your keychain.» Please click «Always Allow» in this dialog, or Fuse will be unable to keep you logged in between sessions.

  • Refreshing previews of large apps on mobile devices is now much faster.
  • You can now Restart a preview from the Viewport menu in order to reset all the app state.
Create class from selection (Pro)
  • You can now create an UX class from an instance element. Effectively this means you can create new components without switching out of Fuse Studio.
Inspector (Pro)
  • Removed "current color" from the Windows color picker, since the new color is updated in real time rather than when the user clicks "ok"
  • Removed MaxLength from the Text inspector. This attribute is deprecated, and the inspector for it has a bug
  • Compact Mode is now always called "Compact Mode". Previously, it was referred to as "Compact View" in some places
  • Gradient stops can now be added from the inspector
  • Added PageControl and Page to the primitives bar
  • Add ClientPanel and Button to the primitives bar
  • Installing Android SDKs (fuse install android) can now be done from the Tools menu
Misc bug fixes
  • Fix crash when attempting to remove root element from hierarchy
  • Fix problem in log view with multiple log messages printed on one line
  • Fix preview not appearing when Fuse is used by multiple user accounts on Mac
  • Fix indentation when moving or adding elements spanning several lines
  • Removing elements using the main menu no longer causes Fuse to crash
  • Fixed an issue where fuse install android would fail on macOS with case sensitive file systems
  • Fixed a (minor) memory leak


Native UI:
  • Fixed bug on iOS that could cause native views from thirdparty libraries to get an incorrect position. (Fixes issues with Firebase AdMob)
  • Added several features to allow navigation/routing from within UX, whereas previously JavaScript code was required.
  • Added ModifyRoute, GotoRoute and PushRoute actions to replace RouterModify. These all have a Path property.
  • Added gotoRoute, pushRoute, and modifyRoute expression events which allow for simple navigation in event handlers.
  • Added Navigator.Pages to bind the local history to an observable/model
  • Added PageControl.Pages to bind the list of available pages to an observable/model
  • Fixed the semantics of PageControl.ActiveIndex to work with dynamic pages. The output, getter, will only be updated when the navigation is intentionally changed to a new page. Previously it would always reflect the current page, which causes problem with dynamic pages. The variation between the desired target and actual target only lasts while the desired target is not yet rooted.
  • Changed how Router maintains history. This resolves several minor issues, including local histories (though this isn't fully exposed yet). It's intended to be backwards compatible for all known use-cases.
  • Changed IRouterOutlet and related types to be internal. This was not meant to be public as it's a private detail of the navigation system and could not be implemented correctly by users.
  • Removed the Navigator IsReusable property. These were deprecated over a year ago. Use Resuse="Any" instead.
  • Removed PageControl.TransitionEasing and Pagecontrol.TransitionDuration. These were deprecated over a year ago. Use a NavigationMotion object instead with GotoEasing and GotoDuration properties.
  • Removed PageIndicator.DotTemplate and PageIndicator.DotFactor. These were deprecated over a year ago. Use a ux:Tempate="Dot" child instead.
  • Removed Navigation.PageData. It was always meant to be internal and has no public use.
  • Allowed GoBack and WhileCanGoBack on the router to properly interact with bound observable/model PageHistory
JavaScript: Optional explicit require() of UX symbols
  • Symbols declared with ux:Name, ux:Dependency or dep are now also available to require() for <JavaScript> modules using the ux: prefix. This allows us to write code that plays nicer with transpilers and linters. Using require for names declared in UX is optional, but may make the code more readable and maintainable, e.g. var router = require("ux:router") over just using router with no declaration.
  • Fixed a problem where horizontal or vertical lines would not draw in the .NET backend.
  • Fixed an issue with attract not updating when using a data binding as the source value
  • Fixed bug where the default font on Android could end up being null.
  • Fixed issue where Images with Mask could end up not displaying. This happened due to unnecessary invalidation of the implicit native GraphicsView in the app root. This invalidation was introduced when the Surface API was implemented for native. Invalidation is now opt-in on ViewHandle
  • Fixed issue where Circles could draw incorrect due to floating point precision
  • Fixed issue where Rectangles could render incorrectly on mobile devices with FP16 precision limitation.
  • Added ScriptPromise. This adds support for passing Promises between Uno and the scripting engine. Very useful when dealing with async stuff and JavaScript
  • Added ScriptReadonlyProperty. This feature lets you expose readonly data in JavaScript. Useful for exposing constants for example

Fixed issue where custom URI schemes were matched too greedily in URLs, making for erroneously intercepted URL requests.

Delay Push Notification Registration on iOS

On iOS you can now put the following in your unoproj file:

    "iOS": {
        "PushNotifications": {
            "RegisterOnLaunch": false

which will stop push notifications registering (and potentially asking for permissions) on launch. Your must then call register() from JS when you wish to begin using push notifications. On android this option & register are silently ignored.

  • Fixed issue where an <Image /> could fail to display inside a <NativeViewHost /> on iOS
  • Fixed an issue where a JPEG image from a misconfigured server using image/jpg would fail to load.
  • Fixed a bug where replacing the whole list of items with an empty list would not immediately remove the items from the UI.
  • Added ScrollViewPage which simplifies the creation of infinite scrolling lists
  • Added missing hit testing from Ellipse. If you relied on there not being any hit testing on an ellipse add HitTestMode="None"
  • Fixed an issue where certain triggers would not skip their animation/actions as part of the Bypass phase. This will not likely affect many projects, but may resolve some spurious issues where animations did not bypass under certain conditions.
  • Fixed an issue where WhileVisibleInScrollView did not respect the Bypass phase for element layout.
    • If you required this behaviour add Bypass="None" to the trigger -- in exceptional cases you can add Bypass="ExceptLayout" to get the precise previous behaviour, but it should not be required, and is only temporarily available for backwards compatibility.
  • Several triggers were modified to properly look up the tree for a target node, whereas previously they may have only checked the immediate parent. The affected triggers are BringIntoView, Show,Hide,Collapse, Toggle, TransitionState, Callback, CancelInteractions, Stop, Play, Resume, Pause, TransitionLayout, BringToFront, SendToBack, EvaluateJS, RaiseUserEvent, ScrollTo. This should only change previous behavior if the action was previously configured incorrectly and did nothing or already found the wrong node. Many of the actions have a Target to target a specific node, or TargetNode to specify where the search begins.
  • Changed/fixed Trigger to provide the trigger itself as the target node to a TriggerAction, previously it'd provide the parent of the trigger. The old behaviour was due to an old tree structure. This should have been updated a long time ago. This allows actions to reference the trigger in which they are contained. If you've created a custom Uno TriggerAction and need the old behaviour modify your Perform(Node target) to use target.Parent. Triggers should in general scan upwards from the target node.
  • Added minimal support to WhileVisibleInScrollView for changes in Element layout updating the status
  • Added support for the Surface API in native UI for iOS. Meaning that Curve, VectorLayer and charting will work inside a NativeViewHost.
  • Fixed issue on Android causing text to align incorrectly if being scrolled and unfocused.
  • Added possibility to use RowAlignment to align the elements in the major direction of the WrapPanel as well as in the minor.
  • Optimized UpdateManager dispatcher to deal better with high numbers of dispatches per frame (as when populating long lists).
  • Optimized how ZOrder was computed which improves layout and tree initialization speed. Inlcudes a minor change on the ITreeRenderer interface, unlikely to affect your code.
  • Optimized how bounding boxes are calculated (improves layout and rendering performance).
  • Optimized how render bounds are compounded for larger lists.
  • Several low-level optimizations that speeds up scenarios with long lists (e.g. scrollviews). Here are the Uno-level details:
    • Optimized the implementation of the Visual.Children collection to be an implicitly linked list. This avoids all memory allocation and shifting in connection with inserting and removing nodes from a parent, and ensures a O(1) cost for all child list manipulations.
    • Introduced new public API: Node.NextSibling<T>() and Node.PreviousSibling<T>(), which can be together with Visual.FirstChild<T>() and Visual.LastChild<T>(). The recommended way of iterating over the children of a Visual is now for (var c = parent.FirstChild<Visual>(); c != null; c = c.NextSibling<Visual>()) where Visual can be replaced with the desired node type to visit.
  • Fuse.Scripting now knows about the JS Date type, allowing instances to be passed to/from Uno in the form of Uno.DateTime objects. This support extends to databinding, NativeModules, ScriptClasss, and the Context.Wrap/Unwrap API.
  • Binding an object that does not implement IArray to a property that expects IArray will now automatically convert the value to an array of length 1.
UpdateManager changes (Uno-level)
  • Breaking change: Several entrypoints on UpdateManager now take a LayoutPriority enum instead of int as the priority argument. Very unlikely to affect user code code.
  • Fixed an issue where writes to FuseJS/Observables would not dispatch in the right order on the UI thread if interleaved with ScriptClass callbacks (slightly breaking behavior).
Fuse.Reactive framework changes (Uno-level)
  • These are breaking changes, but very unlikely to affect your app:
    • The DataBinding, EventBinding and ExpressionBinding class constructors no longer take a NameTable argument.
    • The Name and This expression classes has been removed. The UX compiler will now compile these as Constant expressions that contain the actual objects instead.
    • The IContext interface no longer contains the NameTable property.


C++ backend
  • Don't lazy initialize types without a user-defined static constructor. This removes a bunch of Foo_typeof()->Init() calls from generated code, for instance when accessing a static field, to reduce run-time overhead.
Deprecated importers
  • import BundleFile(FILENAME) and remaining parts of the importer system in Uno.Compiler.ImportServices has been deprecated. We can now pass the filename directly to the operator instead: import(FILENAME). The import operator returns a BundleFile object. The classes texture2D and textureCube contains Load() methods accepting BundleFile which can be used to import texture files, replacing the deprecated texture importers.

| Old syntax | New syntax | |--------------------------------|--------------------------------------| | import BundleFile(FILENAME) | import(FILENAME) | | import Texture2D(FILENAME) | texture2D.Load(import(FILENAME)) | | import TextureCube(FILENAME) | textureCube.Load(import(FILENAME)) |

Removed UXL variable 'Mono'
  • The UXL variable 'Mono' was removed, since the need of it was removed.
Improvements to Android builds
  • Strip SO files in release builds. This can massively reduce the size of the shipping app.
  • Use gradle to generate required .iml files. This should make us more flexible both to changes from Fuse & to changes from Google in Android Studio. There is now only 1 .iml generated and that is in the app sub-directory of the project and only for builds with the -d flag.
Resource Crunching
.NET backend
  • Validation of method signatures and data types when linking external assemblies has been improved. This revealed a few minor problems in UnoCore that has been fixed:
    • Uno.Net.EndPoint: Constructor is now internal because a compatible constructor doesn't exist in .NET.
    • Uno.Threading.Monitor.TryEnter(): Return type is now bool to match .NET.
    • Uno.Text.StringBuilder: This class now maps to System.Text.StringBuilder on .NET.
    • Uno.Tuple<...>: The AppendItems(StringBuilder sb) methods are no longer public because compatible methods don't exist in .NET.
  • Introduced Uno.Compiler.ExportTargetInterop.DotNetOverrideAttribute. This attribute is used to override implementations of static methods in types that are mapped to .NET, so that the Uno implementation is used instead of the existing .NET implementation. We use this on string.Format() because Uno only implements a subset of the functionality.
Uno.DateTime changes (breaking!)
  • Uno.DateTime was changed from being a class to a struct, to make it .NET-compatible
  • The UtcNow property has changed types from being Uno.Time.ZonedDateTime to being Uno.DateTime, to make it .NET compatible
  • The Now property has been made internal until better .NET-compatible support can be provided
Uno compiler
  • The compiler has become stricter about accessing entities from other packages. Previously it was in some cases possible to access internal entities from a different package without getting a build error.
  • The compiler now accepts empty structs. It's no longer necessary to add a dummy field to work around build errors when forward declaring .NET structs for instance.