Flutter and desktop applications
Many of you are interested in developing Flutter's desktop capabilities, which include Windows, macOS, and Linux. In polls and on GitHub, desktop development is one of Flutter’s most notable new features. In the near future we are going to talk more about what we do. We believe that it is worth starting with a review of what has been done by the various teams responsible for Flutter's capabilities. Although support for desktop applications is still at the trial technical version stage, serious work is underway on the corresponding capabilities.
We recently released application profiles and build modes for Windows and Linux - in addition to existing macOS support. For example, if you use the latest Flutter build, Flutter applications can be compiled into Windows executables with the CDMY0CDMY command. To do this, use our AOT compiler production level, which allows you to create machine code for the x64 architecture, which you can run on appropriate computers without installing Flutter.
Features of desktop applications
Whether you are developing an application represented by a standalone executable file, or a web application, desktop applications have some specific features and features. For example, desktop application windows are usually displayed in landscape mode, and their size can be changed. Users typically enter data into applications using a keyboard and mouse, rather than on-screen keyboards and touch input. The controls are optimized considering that desktop applications use special values for visual density when placing controls.
We, at the framework level, have made some changes to Flutter that are aimed at supporting desktop applications.
- When you create a new project in fresh Flutter assemblies, you will see that the default template now includes a link to the CDMY1CDMY property, which is allows to adjust the visual density of controls based on the target application platform. In the layouts of desktop applications, the controls are “packed” denser than in mobile applications. For example, this is used when setting up a text box (CDMY2CDMY), which now offers visual density options compact, comfortable and standard , depending on project parameters.
- We have significantly improved mouse and keyboard support. This includes the ability to work with codes of keyboard keys in Windows, support for right-clicking, support for cursor changes and mouse wheel.
- Now you can use the CDMY3CDMY class to find out on which platform the application is running. When running the application on Windows, macOS and Linux, you can get the corresponding results.
- In the latest release, we added a NavigationRail widget , which is something like a sidebar. This widget is specifically designed to support the capabilities of applications that run on desktop PCs and tablets.
The Dart team has done a great job of improving the Foreign Function Interface (FFI). This helps speed up the implementation of new features in Flutter. For example, for C-based APIs, the CDMY4CDMY library provides a direct mechanism for organizing binding to native code. The Dart runtime makes it possible to invoke dynamically linked libraries and allocate memory on the heap. This mechanism is based on Dart objects.
Here is a code snippet ( here you can find its full version), which is a simple example that shows the appeal to the traditional Win32-API CDMY5CDMY, fully executable by means of the Dart-code:
typedef MessageBoxNative=Int32 Function( IntPtr hWnd, Pointer<Utf16> lpText, Pointer<Utf16> lpCaption, Int32 uType); typedef MessageBoxDart=int Function( int hWnd, Pointer<Utf16> lpText, Pointer<Utf16> lpCaption, int uType); final user32=DynamicLibrary.open('user32.dll'); final win32MessageBox= user32.lookupFunction<MessageBoxNative, MessageBoxDart>('MessageBoxW'); void showMessageBox(String message, String caption) => win32MessageBox( 0, //Нет окна-владельца Utf16.toUtf16(message),//Текст сообщения Utf16.toUtf16(caption),//Заголовок окна 0 //Только кнопка OK ); … showMessageBox('Test Message', 'Window Caption');//этот вызов выглядит как вызов обычной Dart-функции
Here we have CDMY6CDMY aliases representing method signatures for both their native representation and their Dart representation. When we have these aliases, we can load the dynamically linked Windows library, which contains the implementation of the function. To do this, you can use the CDMY7CDMY method, which maps the signatures of the Dart function to a native function. And finally, we, not necessarily, describe a simple functional wrapper that simplifies working with native mechanisms in Dart code. As a result, we get something similar to the following figure.
A simple example of a Windows project that uses the Win32-API MessageBox ()
In fact, the programmer does not have to do all this himself. The fact is that it is likely that someone has already prepared code , which simplifies the work with the APIs you need. Here you can read more about FFI.
Updating the plugin model
Flutter is designed to have a compact core. To equip the framework with additional features, the corresponding functionality is made out in the form of plug-ins and packages that enable integration with the operating systems that Flutter runs on. Plugins and packages can be created not only by Flutter developers, but also by other programmers.
However, given the fact that Flutter is improving support for mobile and desktop platforms, as well as web applications, developing plugins for each platform supported by the framework is becoming more and more difficult. When developing a plugin, it is very likely that you need to combine the efforts of different programmers, each of whom is well versed in some platform.
Here, an approach may come to our aid, according to which a certain basic plug-in describes a common interface that can be independently implemented on different platforms. As a result, as described in the latest material about modern plug-in development, we recently implemented a system in Flutter, which simplifies the collaboration of various authors on plugins.Thanks to this system, you can already explicitly indicate which platforms supported by specific plugin.
We started using this model when working on some basic plugins. Examples of a new approach to collaborative plug-in development can be found here .
Please note that the plugin API for Windows and Linux has not yet been established, therefore, although we advise developers to get acquainted with the new features of Flutter, we are not yet ready to release these features in production. We are also working on adding desktop platform tags to pub.dev.
Run programs on Windows: Win32 and UWP
One interesting aspect of our work related to Windows is that here we are experimenting with different architecture approaches. Flutter, on any platform, is embedded in a small host application that is a container (“embedder”) using an approach similar to that used in game engines like Unity. This embedder application, specific to each platform, provides us with a project entry point. It coordinates its actions with the operating system, working with rendering tools, with user input and with tools that ensure the availability of content. It also supports the event loop.
Windows gives us two ways to create such an application. The first is a mature Win32 programming model that can be used as an entry point for Flutter projects. This approach offers the highest level of backward compatibility with various platforms, such as Windows 7. It allows you to create standard EXE files that many programmers expect to receive as a result of working on a project. Unlike Win32, the modern UWP application model is recommended for Windows 10. This model offers attractive features for creating Flutter applications for special devices, such as Xbox, and for OS Windows 10X , which should be out soon.
Unofficially, we work with various developers and research different solutions. We would love to work more closely with Microsoft in order to improve the quality of Windows applications made with Flutter. Since the Surface device family now includes Android and Windows-based systems, we think Flutter is able to offer Microsoft a powerful platform that allows you to create attractive native applications for a wide variety of devices.
Experiments with desktop applications
Since the features discussed are still at the trial technical version stage, the API and auxiliary tools are still unstable. We have planned many more things that need to be completed before we transfer support for desktop applications to the category of stable features. This also includes improving content accessibility and localization.
If you already want to experience new opportunities, then you need to use the development channel. Support for Windows and Linux is available in the CDMY8CDMY branch, in the place where Flutter is actively developing. MacOS support is available on the CDMY9CDMY branch. There are more stable features, which, however, are not recommended for use in production. You can switch between channels using the CDMY10CDMY or CDMY11CDMY commands. After that, you need to run one of the following commands in order to enable support for the platform you are interested in:
C:\flutter> flutter config --enable-windows-desktop $ flutter config --enable-macos-desktop $ flutter config --enable-linux-desktop
We have already seen how some daring developers started creating desktop applications with the new Flutter features. One of the first such applications was developed for macOS. It's called Sharezone . This is a student planner aimed at the German education market. At first, this project was released as a mobile application.And recently he came out in the desktop version and the version intended for the web.
Sharezone Schulplan is an app for students, teachers and parents. It allows you to plan and track homework, study groups, and schedules
Do you plan to use Flutter to develop desktop applications?