This week in SixtyFPS

13th of September to 19th of September 2021

Posted on September 20, 2021

SixtyFPS is a toolkit to efficiently develop fluid graphical user interfaces for any display: embedded devices and desktop applications. We support multiple programming languages, such as Rust, C++, and JavaScript. Find more information at or go straight to github at


  • Font handling in the OpenGL backend

    A lot of changes this week were concerned with font handling. The overall objective was to improve the methods of locating fonts that can provide glyphs for text to be rendered.

    • Rework the font loading in the GL backend ( 6130e0 )

      The basic idea is to use fontdb's load_system_fonts() mechanism, in conjunction with its built-in mmap support, to get an overview over all installed fonts on macOS, Windows and Linux.

      This may not be the most sophisticated approach, but it's fast through the use of mmap and will allow for additional filtering by glyph coverage.

    • Fix font fallback handling on macOS ( db842e )

      Permit processing the entire font cascade list and only load those fonts that provide glyph coverage for the text to be rendered.

    • GL backend: add basic font fallback support for Linux ( d2923d )

      Use the static (but long) fallback list that we get from fontconfig in the beginning to get a reasonable starting point.

      This works but can be optimized to operate on a trimmed and shorter list, which will speed up the fallback.

    • GL renderer: fix rendering of Text/TextInput when the text property changes in a way that requires different fonts ( cc7ea5 )

      Unfortunately the text property was not included in the property dependency chain for the cached Font. This is fixed by delaying that with a getter function, but in the mid term we should be able to remove this again by lazy font resolution.

  • CMake

    Another focus was on improving CMake builds for C++. What used to be a three-step build process - library, compiler, generate C++ headers - folds the last step into the build of the library using a Cargo build script.

    • Fix make install in the C++ build running cbindgen ( 4f1586)

      Make install would trigger the generated_headers_target CMake custom command - due to the use of add_dependencies - and that would end up running cbindgen. That in turn breaks "make install" when it's run in an environment that doesn't have cargo in PATH (for example when using "sudo make install").

    • Bump run-cmake Github Action version in the CI ( 26ed01 )

      The new version promises improved diagnostics (log files) and security fixes.

    • Improve cmake diagnostics ( 0e191c )

      Print a feature summary. This also helps diagnose CI builds.

    • Bump minimum required CMake version from 3.16 to 3.19 (562842 )

      The re-organization of the C++ header generation requires the use of the CORROSION_ENVIRONMENT_VARIABLES target property, which in turn requires CMake >= 3.19.

  • New API for the interpreter to introspect globals
    • Add support for introspecting globals in the interpreter Rust API ( a855d8 )

      Add three straight-forward functions:

      • pub fn globals(&self) -> impl Iterator<Item = String> + '_
      • pub fn global_properties(&self, global_name: &str) -> Option<impl Iterator<Item = (String, ValueType)> + '_>
      • pub fn global_callbacks(&self, global_name: &str) -> Option<impl Iterator<Item = String> + '_>

      Implementation wise this requires passing along a way to get the non-normalized (original) export name, as globals() should return the names as the developer/designer specified them, and global_properties()/global_callbacks() normalizes.

    • Add C++ API to introspect exported global singletons in the interpreter ( c3d0fd )

      This adds the necessary shims to expose the same API as Rust.

  • Fixes
    • Fix listview not updating its geometry in Rust when the entire model is changed ( 5742a1 )

      The geometry tracker did not track the model property itself, so it did not become dirty.

      Fixes #500

    • Fix panic when using height-for-width element in natively styled TabWidget ( 85a46c )

      The metrics properties and the implementation of layout_info needs to strictly reading cross-axis properties to avoid circular dependencies.

      This patch applies a INT_MAX / 2 on the cross-axis to QStyle when querying. Mostly the styles appear to just add/subtract margins, so this value should not produce overflows while still providing an approximation of "infinite" :)

      Fixes #412

    • Fix native widget rendering when the window is inactive ( ed3d84 )

      Set QStyle::State_Active conditional to whether the window is active, which maps to Qt's active window concept and winit's has-focus (until we render popups differently).

    • Fix rendering of the current tab in the natively styled tab widget on macOS ( 1b64db )

      It was impossible to see which tab was the current tab. Ensure that we set State_Active, like we do for the other styled controls.

      Later, the active state should be tied to whether the window is "active" or not.


News about applications built with SixtyFPS

  • cargo-ui
    • Improve rustup toolchain discovery ( 8904f0 )

      Show a label while refreshing the toolchains and make it possible to terminate cargo-ui while the rustup process is still running (tested with a yield_now() loop :)

    • Fix features tab being visible under the dependencies pan ( d85a01 )

      The colspan was wrong, the overall layout has only four columns.

Please reach out to if you have news to add here!


28 patches were committed.