Blog

All Blog Posts  |  Next Post  |  Previous Post

TMS WEB Core and More with Andrew:
Miletus Desktop Intro

Thursday, July 21, 2022

Photo of Andrew Simard

While TMS WEB Core can be used to develop and deploy fully featured web applications, including PWA apps, it is by no means limited to just web applications. There are several more application types that can be created directly from a TMS WEB Core project. Both the Electron framework and TMS's own Miletus framework can be used to deploy applications to other environments. Today we're going to have a look at how to use Miletus to develop and deploy desktop apps on Windows, macOS, and Linux. We'll cover using Miletus for developing Raspberry Pi projects another time.


Motivation.

If we've got an excellent web application development tool, why do we need desktop applications at all? It's a good question. And the answer, quite often, is that we don't. This is what has made the web such an important platform, after all. And also what makes products like Chrome notebooks as popular as they are. You can accomplish quite a lot using just web applications, and for many people, it is now possible to get by exclusively with web applications alone.  Products like TMS WEB Core are making this easier all the time by being able to develop substantially better applications with access to more data and more systems than ever before. And without question, web technologies have come quite a long way in a relatively short period of time. 

However, there are still many situations that come up where the browser sandbox is too restrictive to accomplish certain tasks. And I'm sure we're all well aware that the browser sandbox and its rules are in place for very good reasons. So while web technologies will continue to evolve, there are some places it just isn't going to reach anytime soon, and that's where desktop apps come in. Here are a few examples where a desktop application solution might win out over a web application solution.

  • An application needs access to directly read and write to the local filesystem.
  • Application data is not permitted to leave a location (IE, saving to 'the cloud' poses unacceptable security risks).
  • An application needs access to hardware that does not have an equivalent (or performant enough) web interface.
  • Access to the application needs to be more strictly controlled.
  • Application changes need to be more strictly controlled (i.e., SOX, ISO9000-type stuff).
  • Users work in an environment where web browsers aren't well-supported.
  • Users work in an environment where desktops are strictly locked down in terms of application access.
  • An application needs access to OS-level functionality that a browser does not have access to.
  • Desire to standardize the application interface (avoiding non-standard browser 'chrome' or plugins that might interfere).

Granted, there are many kinds of complexity at work here, and no doubt there are just as many ways to address certain problems. For example, a web application could be served up within a local network that has no external access at all, ensuring that data doesn't leave that location. And there's even an evolving web standard for accessing serial ports. Crazy, really. But in any event, there may be solid reasons for having a desktop version of a web application (or even a mobile version beyond what can be accomplished with a PWA-compliant application).  Whatever the rationale, Miletus is here to help address it.

Getting Started.

For our example application, we're going to carry on with the Leaflet example that we covered a couple of days ago, an almost minimalist interactive mapping web application. It has been updated slightly to fix a few minor internal errors, to be more 'responsive' so that it can be resized to fit its container, and also to have a slightly improved geofence data entry interface, where you can cancel the entry, see the points as a polyline while you're entering them, change the color of the geofence created, as well as delete geofences. To get this all working, we start by creating a new TMS WEB Core Miletus project from the regular list of templates. 


TMS Software Delphi  Components
TMS WEB Core Project Templates
.

This creates a new blank project as expected. The first thing that is noticeably different is that there are a few more Build Configurations available. Note that this project was created using TMS WEB Core v2.0.0.2 and that the list of available Build Configurations is likely to change over time.


TMS Software Delphi  Components
Miletus Build Configurations.

For today, we'll be focusing just on the Win64, Linux64, and MacOS64-Intel variants. We can test it out right away by just adding a TWebButton to the form and running the project. By default, it creates a Win32 executable that launches and displays the button. Here's what it looks like.

TMS Software Delphi  Components
Basic Miletus App.

This was created in 'debug' mode, so there are some extra menu items available. One small curiosity is that it takes a bit of time for the button to appear, presumably because the browser used to render the application is being loaded in the background. These processes can be seen in Task Manager. Restarting the app shows the button almost immediately, so perhaps not a big issue, either way, just a curiosity.

The compiled binary file is a Win32 executable that is about 9.6 MB in size. Being a Win32 app also means that it can be compressed with tools like UPX, something I've used when deploying my regular Delphi projects for as long as I can remember. There are various tradeoffs to such tools, with a big one being that it tends to make antivirus and antimalware software throw fits. Whether that is a good or a bad side effect is perhaps an interesting debate. In any event, running UPX against this binary shrinks it down to a more palatable 3.6 MB without any discernible difference.


We've Got Options.

If you had a chance to read the recent article in this series about TMS WEB Core PWA applications, you'll recall that there wasn't much difference visible in the project until we got a look at the project options. Same deal here, where things look sort of the same, but with an updated list of options where we can set things like icons for the various platforms. Much like the PWA scenario.

TMS Software Delphi  Components
Miletus Project Options.

These should be mostly familiar by now, with nothing for us to change at the moment, but be sure to keep these in mind when deploying apps with proper icons and so on. There is an option to 'Start Miletus with developer tools' which will launch another window automatically. This same window can be launched from within the app. This is where the usual browser console can be found, for example.

Converting An Existing Project to Miletus.

It is a relatively trivial project in this case, but when moving our Leaflet example into the Miletus project, unfortunately, wasn't quite as simple as just copying the unit over. Fortunately, this is a very small project, so recreating it inside a Miletus project was not difficult. It seems a Miletus form is different from a regular form, but perhaps that can be adjusted just by changing the form definition. Something to try another day.

(Update: Yep, tried it with another project. Had to change the Form declaration from TWebForm to TMiletusForm, and also add WEBLib.Miletus to the uses clause, then everything else fell perfectly into place)

For now, we can just create the handful of controls and be on our way. A few Font Awesome icons were added to the mix, and the layout was upgraded a little. We also have to remember to copy over the changes that we made to the Project.html file and because this wasn't created as a Bootstrap project, we'll have to add that in as well.

    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/leaflet@1.8.0/dist/leaflet.min.css">
    <script src="https://cdn.jsdelivr.net/npm/leaflet@1.8.0/dist/leaflet.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/universal-geocoder@0.14.2/dist/universal-geocoder.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@latest/dist/js/bootstrap.bundle.min.js" type="text/javascript"></script>
    <link crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/bootstrap@latest/dist/css/bootstrap.min.css" rel="stylesheet"/>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@6.1.1/css/all.min.css">

With those in place, we can just run the app and get our updated Win32 Project1.exe file. 


TMS Software Delphi  Components
Leaflet Example as a Miletus Win32 App.

This works pretty well. Debugging via the console is available, just be aware that the underlying browser is now Microsoft Edge instead of whatever other browser you might have been using. It is functionally equivalent to Google Chrome, given that they are the same under the hood, so not something to be terribly concerned with. The generated Project1.exe clocks in at about the same 9.6 MB as one might expect, given that the project is so very small.

Building Win64.

To get a Win64 version, not much effort is required. Double-clicking on the Build-Win64 entry (or Debug-Win64 if you prefer) in the Build Configurations list is about all that is needed here. In the TMSWeb\Build-Win64 directory, there is now a Project1.exe and its support DLL, WebView2Loader_x64.dll. It of course looks identical to the Win32 version but is now around 13.8 MB instead of 9.6 MB. Running it through UPX also works, resulting in a compressed EXE that comes in at around 4.1 MB.

How do you tell a Win32 executable from a Win64 executable? There are a few ways. One is to add 'Platform' as a column in the Windows Task Manager, making it easy to tell which version is running. Note that for some reason, running both Project1.exe versions simultaneously didn't work, but if one was renamed it worked fine. In this case, the Win64 version was also put through UPX.
 

TMS Software Delphi  Components
Windows Task Manager.

Another way to distinguish between Win32 and Win64 apps is to right-click on the executable in Windows Explorer, select Properties, and then have a look at what Compatibility options are available. Win64 executables will only offer Windows 7 and later options, whereas Win32 executables will offer options going all the way back to Windows 95.

Building Linux64.

The same approach is used here. Double-clicking on the Build-Linux64 entry (or Debug-Linux64) in the Build Configurations list and then running the project creates the expected executable file in the TMSWeb\Build-Linux64 directory. This comes in at around 25.6 MB. UPX also works here, compressing it down to about 7.2 MB.

The Linux system I have currently is Fedora 33 running KDE, so not the most current or the most popular anything, really. There are some Linux prerequisites to get this to work. GTK and WebKit are likely the biggest ones. Also, it required an SSL connection to the mapping provider and doesn't even prompt (or allow) the local location to be looked up. Likely something that could be resolved, but wasn't working immediately. Other Linux distributions will have their own systems for updating libraries and dependencies, but for Fedora, they look like this.

sudo dnf install gtk3-devel
sudo dnf install webkit2gtk3-devel

With those in place, launching the executable works pretty well. Here's a screenshot of what it looks like. I think something is amiss with the rounded corners of the actual map. A little fiddling didn't seem to produce any changes in the output, so another item for the to-do list. It otherwise works fine.

TMS Software Delphi  Components
Leaflet Example as a Linux64 app.

Determining whether a Linux executable is 32-bit or 64-bit can be accomplished just using the 'file' command. The first is what is produced directly, the second is after it has been run through UPX.

# file Project1
Project1: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=e64a7f5c4dd2dfb5cbc38487c60f5bf5e1cd9695, stripped

# file Project1-Linux64
Project1-Linux64: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, no section header


Beyond that, the browser developer tools also work and are embedded within the window rather than displayed in a separate window as is done under Windows.

TMS Software Delphi  Components
Miletus Linux64 with Developer Tools.

Overall this works pretty well, all things considered. No need for anything outside of Delphi to create the executables and once created, nothing really to do when it comes to deploying them. There's even an icon created for the Linux desktop.

Building macOS.

Same deal here, and naturally no dependencies or other issues when deploying to the Mac. And this executable is built directly - no need for any kind of tool to talk to macOS to get it to compile or anything. 

In this example, it is running on macOS Mojave. I don't know if there is a UPX equivalent for macOS, but the app bundle in this case (for the Debug version) came in at around 41.7 MB.

(Update: UPX can compress macOS executables as well! The main 'Miletus' component of the app package is similar to Linux, and compressed from about 26 MB down to about 7 MB, cutting the overall package nearly in half, from 41.7 MB to 22.5 MB).  

It seems to have the same issues with rounding as the Linux version, but that could be related to the fact that they are both using WebKit instead of Chrome, but nothing to be too alarmed about. Well, I'm alarmed, but not likely of general concern. In any event, here's what it looks like.

TMS Software Delphi  Components
Miletus Example running under macOS Mojave.

Again, as with Linux, nothing else is needed other than Delphi and TMS WEB Core to produce the macOS executable. This is quite remarkable really, as most solutions to this kind of problem require access to Xcode to compile the project. The macOS build options also include both Intel and ARM, so it seems that we're already set to work with the latest M1 and M2 hardware. The menu appears as a typical macOS-style menu at the top. However, I didn't see an option to show the developer tools interface. Another item for the to-do list. The "Find Me" option also wasn't working here.

A Solid Start.

And with that, we've got our app running as a web page, potentially even as a PWA, as well as on Windows, Linux, and macOS. That's also quite remarkable, really! No small feat. That covers quite a lot of use cases, and even the PWA option could cover most mobile use cases if necessary. So with one set of source code, we've basically got an app that runs on nearly every modern environment.

Future posts about Miletus will explore some of the OS-specific options that are available beyond what TMS WEB Core can do in the browser. And we'll have an in-depth look at Raspberry Pi as well.

Download the full source code of this sample project here.

Follow Andrew on 𝕏 at @WebCoreAndMore or join our
𝕏
Web Core and More Community.



Andrew Simard




This blog post has not received any comments yet.



Add a new comment

You will receive a confirmation mail with a link to validate your comment, please use a valid email address.
All fields are required.



All Blog Posts  |  Next Post  |  Previous Post