{"id":13044,"date":"2024-07-09T21:28:45","date_gmt":"2024-07-09T21:28:45","guid":{"rendered":"https:\/\/www.fhug.org.uk\/kb\/?post_type=kb_article&#038;p=13044"},"modified":"2024-07-12T11:50:57","modified_gmt":"2024-07-12T11:50:57","slug":"writing-plugins-compatible-with-apple-mac-and-linux","status":"publish","type":"kb_article","link":"https:\/\/www.fhug.org.uk\/kb\/kb-article\/writing-plugins-compatible-with-apple-mac-and-linux\/","title":{"rendered":"Writing Plugins Compatible With Apple Mac and Linux"},"content":{"rendered":"<p>There are some key differences in how plugins behave in emulator software for Mac and Linux systems that authors need to be aware of to avoid unexpected effects or application crashes.<\/p>\n<h2>Scope<\/h2>\n<span class=\"fh\" style=\"font-size: 17px !important; line-height: 21.4286px !important;\">\u0192<span style=\"color:#73B262; font-weight: bold;\">h<\/span><\/span> is a Windows application, and not designed to run under either MacOS or Linux, which are both Unix-derived Operating Systems. However, in common with many Windows applications, it can be used on these systems via either an emulator (which simulates the Windows environment) or VM (Virtual Machine, which enables Windows to run inside a protected space within the host system).<\/p>\n<p>The most common emulators are based on WINE, an open-source application. This is most commonly implemented on Macs via commercial packages such as Crossover or PlayOnMac that provide additional features, but on Linux use of raw WINE or packaged with PlayOnLinux, both of which are free, are more common.<\/p>\n<p>Both Crossover and WINE are being developed continuously, so features and therefore plugin compatibility can vary over time. Crossover for the Mac and WINE 9.0 (the latest stable version at the time of writing) appear to be very similar in how they support <span class=\"fh\" style=\"font-size: 17px !important; line-height: 21.4286px !important;\">\u0192<span style=\"color:#73B262; font-weight: bold;\">h<\/span><\/span>, so are the basis of these notes. Unqualified references to WINE should therefore be read as applying to either Mac\/Crossover or Linux\/WINE 9.0. Older versions of WINE will have additional issues, but upgrading to 9.0 is recommended for use with <span class=\"fh\" style=\"font-size: 17px !important; line-height: 21.4286px !important;\">\u0192<span style=\"color:#73B262; font-weight: bold;\">h<\/span><\/span>.<\/p>\n<h2>Can Plugins Detect Emulators?<\/h2>\n<p>We have not identified a definitive method that a plugin can use to determine whether it is running inside an emulator or not, as WINE does not appear to have a supported method for its detection. Some old plugins have used differences in the detailed <span class=\"fh\" style=\"font-size: 17px !important; line-height: 21.4286px !important;\">\u0192<span style=\"color:#73B262; font-weight: bold;\">h<\/span><\/span> file structure to detect an emulator, but this no longer works as WINE now replicates Windows user file structures precisely.<\/p>\n<p>Unix-derived file systems do not use drive letters, and denote directories using forward slashes (\/), with a root at simply \/. Both MacOS and Linux create two fixed directories off the root, \/bin for binary system files and \/etc for text-based configuration files (similar in concept to Windows .ini files). WINE acts as a bridge between the host Unix-derived file system and the Windows application, so translates the root directory as Z:\\, and these directories as Windows folders Z:\\bin and Z:\\etc, respectively. If a plugin needs to know if it is inside WINE, all it has to do is check for the presence of these folders. If they do not exist, it is definitely a native Windows installation. If they do exist, it is highly likely to be WINE, as the only other explanation is that the user has mapped a network drive or non-system local drive to Z:\\, which also contains both of these folders, an extremely unlikely circumstance.<\/p>\n<p>An alternative method is to check whether Emulator Compatibility Mode has been selected (available in <a href=\"#!\" class=\"cs_tooltip\" fhugtt=\"This is the menu across the top of the main Family Historian windows. The &gt; denotes a submenu\">Tools&nbsp&gt;&nbspPreferences&#8230;&nbsp&gt;&nbspAdvanced&#8230;<\/a>, and stored at Registry key HKLM\\SOFTWARE\\Calico Pie\\Family Historian\\2.0\\Preferences\\Emulator-Compat-Mode). However, exactly what this setting does and its use in future versions of <span class=\"fh\" style=\"font-size: 17px !important; line-height: 21.4286px !important;\">\u0192<span style=\"color:#73B262; font-weight: bold;\">h<\/span><\/span> is undocumented, and it relies on users setting the option correctly.<\/p>\n<h2>Processing Emulator Errors<\/h2>\n<p>Unfortunately, conventional error handling routines do not work for WINE errors, as WINE may stop with a fatal error message and close <span class=\"fh\" style=\"font-size: 17px !important; line-height: 21.4286px !important;\">\u0192<span style=\"color:#73B262; font-weight: bold;\">h<\/span><\/span> before the plugin error handling has been called.<\/p>\n<h2>Processing Family Historian Data<\/h2>\n<span class=\"fh\" style=\"font-size: 17px !important; line-height: 21.4286px !important;\">\u0192<span style=\"color:#73B262; font-weight: bold;\">h<\/span><\/span> API functions and objects such as Item, Date and Rich Text pointers appear to be fully transparent to the use of WINE, so simple plugins that just process <span class=\"fh\" style=\"font-size: 17px !important; line-height: 21.4286px !important;\">\u0192<span style=\"color:#73B262; font-weight: bold;\">h<\/span><\/span> data operate in exactly the same way in an emulator as in a native Windows system.<\/p>\n<h2>Cosmetic Display Issues<\/h2>\n<p>Windows applications operating under WINE generally have a slightly different appearance compared with native Windows, as they create their own principal user interface elements such as window controls and message prompts, as well as using different default fonts. In general, these are no more significant than variations between different versions of Windows, as each new iteration comes with an &#8220;update&#8221; and &#8220;refresh&#8221; of the user interface styling elements.<\/p>\n<p>What may be more significant is font differences in the IUP library in the two systems, and their effect on the user interface. All combinations of Windows 10\/11 and <span class=\"fh\" style=\"font-size: 17px !important; line-height: 21.4286px !important;\">\u0192<span style=\"color:#73B262; font-weight: bold;\">h<\/span><\/span> 6\/7 use 9 pt Segoe UI as the default IUP font. This is a Microsoft font, and current versions of WINE use 8 pt Tahoma, a significantly smaller font.<\/p>\n<p>Version 7 of <span class=\"fh\" style=\"font-size: 17px !important; line-height: 21.4286px !important;\">\u0192<span style=\"color:#73B262; font-weight: bold;\">h<\/span><\/span> enables the user to set a preferred font for the general appearance of the app, and it is best practice for new plugins to respect this choice when running in <span class=\"fh\" style=\"font-size: 17px !important; line-height: 21.4286px !important;\">\u0192<span style=\"color:#73B262; font-weight: bold;\">h<\/span><\/span>7, either by using fhUtils() or reading the appropriate Registry key directly, as it gives plugin menus a similar appearance to the main app. Unfortunately, while this may enhance overall plugin appearance, it does not guarantee consistent presentation between Windows and WINE, as the same font may be rendered at a different absolute screen size.<\/p>\n<p>Advanced users who share either plugin or <span class=\"fh\" style=\"font-size: 17px !important; line-height: 21.4286px !important;\">\u0192<span style=\"color:#73B262; font-weight: bold;\">h<\/span><\/span> font settings between Windows and WINE may also run into difficulties, as they have different font sets, and what is available in one may not be available in the other, but this is probably a very niche application.<\/p>\n<p>These issues are not unique to WINE due to the potential font variability that <span class=\"fh\" style=\"font-size: 17px !important; line-height: 21.4286px !important;\">\u0192<span style=\"color:#73B262; font-weight: bold;\">h<\/span><\/span> 7 provides, and are largely overcome by ensuring that plugins use relative size (expressed relative to the average character size in the active font) rather than absolute size in screen pixels. Plugin authors should check their plugins with a range of fonts (say a narrow 8 pt font to a wide 14 pt option) to ensure that there are no unexpected effects, particularly for plugins that have relatively busy menus.<\/p>\n<h2>Known Incompatibilities<\/h2>\n<h3>File Access Issues<\/h3>\n<p>Windows and Unix-derived operating systems have significant differences in how files are defined, so it is perhaps not surprising that this is the area that most affects <span class=\"fh\" style=\"font-size: 17px !important; line-height: 21.4286px !important;\">\u0192<span style=\"color:#73B262; font-weight: bold;\">h<\/span><\/span> plugins.<\/p>\n<p>Lua originated in the Unix world, so the basic language and its libraries has a much more &#8220;Unix feel&#8221; to it than Windows. The standard library for Lua file management is the Lua File System (lfs in the Unix-preferred lower case style), which is provided with <span class=\"fh\" style=\"font-size: 17px !important; line-height: 21.4286px !important;\">\u0192<span style=\"color:#73B262; font-weight: bold;\">h<\/span><\/span>. File attributes are retrieved using the lfs.attributes(..) function, which retrieves all Unix properties, but not those such as ShortName, ShortPath or Type that are undefined in Unix. Unix files are not subject to the 8+3 length limit of DOS and pre-95 versions of Windows, so do not need them.<\/p>\n<p>Unfortunately, lfs does not support Unicode (non-Latin file and path names), so plugins that need this facility now use the Microsoft File System Object (FSO) for file management, which is Unicode compatible. This is most conveniently done for new plugins via the provided fhFileUtils() library, which provides a convenient wrapper for FSO functions, but for simple file and folder management it is not difficult to use FSO directly if backwards compatibility is required.<\/p>\n<p>WINE does not support retrieving the Windows-only file and folder attributes Short Name, Short Path or Type, and any attempt to do so will cause an immediate crash. These specific properties are highly unlikely to be required for <span class=\"fh\" style=\"font-size: 17px !important; line-height: 21.4286px !important;\">\u0192<span style=\"color:#73B262; font-weight: bold;\">h<\/span><\/span> plugins, but early versions of both fhFileUtils() or personal variants of that used in store plugins for backwards compatibility retrieved all properties for convenience. These have now been removed from the latest version of fhFileUtils(..) (<span class=\"fh\" style=\"font-size: 17px !important; line-height: 21.4286px !important;\">\u0192<span style=\"color:#73B262; font-weight: bold;\">h<\/span><\/span> 7.0.23 or later), and will gradually be removed from existing store plugins in due course.<\/p>\n<p>Perhaps more surprisingly, WINE also does not support the various timestamp attributes for folders (perhaps because Windows folders have significant differences to Unix directories, which are only files with specific attributes). These have also now been made optional in fhFileUtils(..). There is currently no recommended method for obtaining Unicode folder timestamps in plugins, other than copying the folder to a &#8220;safe&#8221; name and using lfs, which could potentially involve very large folders.<\/p>\n<h3>Registry Settings<\/h3>\n<p>Occasionally, a plugin may need to read (and exceptionally modify, if it is part of the plugins stated function) a <span class=\"fh\" style=\"font-size: 17px !important; line-height: 21.4286px !important;\">\u0192<span style=\"color:#73B262; font-weight: bold;\">h<\/span><\/span> Registry setting. The application-specific part of the WINE Registry is managed by <span class=\"fh\" style=\"font-size: 17px !important; line-height: 21.4286px !important;\">\u0192<span style=\"color:#73B262; font-weight: bold;\">h<\/span><\/span>, so is fully compatible with operation in native Windows.<\/p>\n<p>The system-specific part of the WINE Registry is NOT the full Windows version, and does not support all Windows keys. Store plugins are specifically prohibited from modifying system Registry settings, but may need to read a setting such as Windows colours, locale, etc. Such plugins should be tested in WINE to ensure that the required setting is supported.<\/p>\n<h3>Windows Commands<\/h3>\n<p>Exceptionally, a Store plugin may need to call a Windows command directly in order to achieve something that cannot readily be done in any other way, such as reading Registry keys to and from file for backup or restore, or copying a large number of files automatically. Not all such commands are supported in WINE, and the following table lists known supported and unsupported examples:<\/p>\n<table style=\"border-collapse: collapse; width: 100%;\">\n<tbody>\n<tr>\n<td style=\"width: 33.3333%;\">Command<\/td>\n<td style=\"width: 33.3333%;\">Supported<\/td>\n<td style=\"width: 33.3333%;\">Typical Use<\/td>\n<\/tr>\n<tr>\n<td style=\"width: 33.3333%;\">reg<\/td>\n<td style=\"width: 33.3333%;\">yes<\/td>\n<td style=\"width: 33.3333%;\">reg import and reg export are used for backup and restore<\/td>\n<\/tr>\n<tr>\n<td style=\"width: 33.3333%;\">robocopy<\/td>\n<td style=\"width: 33.3333%;\">no<\/td>\n<td style=\"width: 33.3333%;\">copying multiple files, similar to long-deprecated xcopy command but many more options<\/td>\n<\/tr>\n<tr>\n<td style=\"width: 33.3333%;\">xcopy<\/td>\n<td style=\"width: 33.3333%;\">yes<\/td>\n<td style=\"width: 33.3333%;\">more restricted version of robocopy<\/td>\n<\/tr>\n<tr>\n<td style=\"width: 33.3333%;\">taskkill (PowerShell)<\/td>\n<td style=\"width: 33.3333%;\">no<\/td>\n<td style=\"width: 33.3333%;\">close <span class=\"fh\" style=\"font-size: 17px !important; line-height: 21.4286px !important;\">\u0192<span style=\"color:#73B262; font-weight: bold;\">h<\/span><\/span> automatically (subject to specific approval from Plugin Store Admin)<\/td>\n<\/tr>\n<tr>\n<td style=\"width: 33.3333%;\">get-process (PowerShell)<\/td>\n<td style=\"width: 33.3333%;\">no<\/td>\n<td style=\"width: 33.3333%;\">detect multiple instances of <span class=\"fh\" style=\"font-size: 17px !important; line-height: 21.4286px !important;\">\u0192<span style=\"color:#73B262; font-weight: bold;\">h<\/span><\/span><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>&nbsp;<\/p>\n","protected":false},"template":"","fh_version":[15,739],"skill_level":[18],"topic":[73],"class_list":["post-13044","kb_article","type-kb_article","status-publish","hentry","fh_version-v6","fh_version-v7","skill_level-advanced","topic-writing-plugins"],"_links":{"self":[{"href":"https:\/\/www.fhug.org.uk\/kb\/wp-json\/wp\/v2\/kb_article\/13044","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.fhug.org.uk\/kb\/wp-json\/wp\/v2\/kb_article"}],"about":[{"href":"https:\/\/www.fhug.org.uk\/kb\/wp-json\/wp\/v2\/types\/kb_article"}],"wp:attachment":[{"href":"https:\/\/www.fhug.org.uk\/kb\/wp-json\/wp\/v2\/media?parent=13044"}],"wp:term":[{"taxonomy":"fh_version","embeddable":true,"href":"https:\/\/www.fhug.org.uk\/kb\/wp-json\/wp\/v2\/fh_version?post=13044"},{"taxonomy":"skill_level","embeddable":true,"href":"https:\/\/www.fhug.org.uk\/kb\/wp-json\/wp\/v2\/skill_level?post=13044"},{"taxonomy":"topic","embeddable":true,"href":"https:\/\/www.fhug.org.uk\/kb\/wp-json\/wp\/v2\/topic?post=13044"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}