Qt for HarmonyOS/platform limitations: Difference between revisions
HarmonyOS Platform Limitations |
New entry: "Clipboard" / "Pasteboard invokes the record provider prematurely when a record has no directly-added entry" |
||
| (5 intermediate revisions by 2 users not shown) | |||
| Line 1: | Line 1: | ||
This page documents known platform limitations of HarmonyOS that affect Qt behavior. | This page documents known platform limitations of HarmonyOS that affect Qt behavior. These limitations stem from HarmonyOS security policies, missing system features, or deprecated APIs. Each entry includes its confirmation status and a reference to the corresponding public bug report. | ||
These limitations stem from HarmonyOS security policies, missing system features, | |||
or deprecated APIs. Each entry includes its confirmation status and a reference to | |||
the corresponding public bug report. | |||
Some items below are still under verification with Huawei and may be refined as | Some items below are still under verification with Huawei and may be refined as more information becomes available. | ||
more information becomes available. | |||
__TOC__ | __TOC__ | ||
| Line 12: | Line 8: | ||
=== chmod() / QFile::setPermissions() not supported === | === chmod() / QFile::setPermissions() not supported === | ||
The HarmonyOS security model does not permit <tt>chmod()</tt> or <tt>fchmod()</tt> | The HarmonyOS security model does not permit <tt>chmod()</tt> or <tt>fchmod()</tt> on existing files. As a result, <tt>QFile::setPermissions()</tt> is not supported on HarmonyOS for existing files and always returns <tt>false</tt>. | ||
on existing files. As a result, <tt>QFile::setPermissions()</tt> is not supported | |||
on HarmonyOS for existing files and always returns <tt>false</tt>. | |||
Note that operations that set permissions on a freshly created file descriptor | Note that operations that set permissions on a freshly created file descriptor — for example <tt>QFile::copy()</tt>, which uses <tt>fchmod()</tt> internally on the newly created destination — are unaffected. | ||
— for example <tt>QFile::copy()</tt>, which uses <tt>fchmod()</tt> internally | |||
on the newly created destination — are unaffected. | |||
Huawei's official response: | Huawei's official response: | ||
<blockquote>Due to security concerns, the system review for this interface was cancelled, | <blockquote>Due to security concerns, the system review for this interface was cancelled, and there is no alternative interface.</blockquote> | ||
and there is no alternative interface.</blockquote> | |||
'''Status:''' Confirmed by Huawei.<br> | '''Status:''' Confirmed by Huawei.<br>'''Impact:''' <tt>QFile::setPermissions()</tt> is a no-op on HarmonyOS for existing files.<br>'''Reference:''' [https://bugreports.qt.io/browse/QTBUG-146619 QTBUG-146619] | ||
'''Impact:''' <tt>QFile::setPermissions()</tt> is a no-op on HarmonyOS for existing | |||
files.<br> | |||
'''Reference:''' [https://bugreports.qt.io/browse/QTBUG-146619 QTBUG-146619] | |||
=== symlink() not available for third-party applications === | === symlink() not available for third-party applications === | ||
<tt>::symlink()</tt> and its ArkTS equivalent <tt>fs.symlink</tt> are unavailable | <tt>::symlink()</tt> and its ArkTS equivalent <tt>fs.symlink</tt> are unavailable to third-party applications on HarmonyOS. <tt>QFile::link()</tt> and any functionality depending on symbolic links will fail with <tt>EACCES</tt> (error code 13900012). | ||
to third-party applications on HarmonyOS. <tt>QFile::link()</tt> and any | |||
functionality depending on symbolic links will fail with <tt>EACCES</tt> | |||
(error code 13900012). | |||
Huawei's official response: | Huawei's official response: | ||
<blockquote>fs.symlink is currently not available for third-party applications. | <blockquote>fs.symlink is currently not available for third-party applications. The official documentation will be updated accordingly.</blockquote> | ||
The official documentation will be updated accordingly.</blockquote> | |||
'''Status:''' Confirmed by Huawei.<br> | '''Status:''' Confirmed by Huawei.<br>'''Workaround:''' None available at this time.<br>'''Reference:''' [https://bugreports.qt.io/browse/QTBUG-146621 QTBUG-146621] | ||
'''Workaround:''' None available at this time.<br> | |||
'''Reference:''' [https://bugreports.qt.io/browse/QTBUG-146621 QTBUG-146621] | |||
=== stat() returns EACCES on system paths === | === stat() returns EACCES on system paths === | ||
<tt>stat()</tt> returns <tt>EACCES</tt> (errno 13) when called on system paths | <tt>stat()</tt> returns <tt>EACCES</tt> (errno 13) when called on system paths such as <tt>/bin/sh</tt> on HarmonyOS. This causes <tt>QFileInfo::isFile()</tt> to return <tt>false</tt> for system executables, while <tt>QFileInfo::exists()</tt> and <tt>QFileInfo::isExecutable()</tt> (which use <tt>access()</tt> internally) return <tt>true</tt>. | ||
such as <tt>/bin/sh</tt> on HarmonyOS. This causes <tt>QFileInfo::isFile()</tt> | |||
to return <tt>false</tt> for system executables, while | |||
<tt>QFileInfo::exists()</tt> and <tt>QFileInfo::isExecutable()</tt> | |||
(which use <tt>access()</tt> internally) return <tt>true</tt>. | |||
As a consequence, <tt>QStandardPaths::findExecutable()</tt> cannot locate system | As a consequence, <tt>QStandardPaths::findExecutable()</tt> cannot locate system executables on HarmonyOS. | ||
executables on HarmonyOS. | |||
'''Status:''' | '''Status:''' Not yet confirmed by Huawei.<br>'''Reference:''' [https://bugreports.qt.io/browse/QTBUG-146625 QTBUG-146625] | ||
'''Reference:''' [https://bugreports.qt.io/browse/QTBUG-146625 QTBUG-146625] | |||
=== open() with trailing slashes does not fail as expected === | === open() with trailing slashes does not fail as expected === | ||
On Linux, <tt>open("qwe//", O_RDWR|O_CREAT|O_CLOEXEC, 0666)</tt> fails with | On Linux, <tt>open("qwe//", O_RDWR|O_CREAT|O_CLOEXEC, 0666)</tt> fails with <tt>EISDIR</tt> because trailing slashes imply a directory path. On HarmonyOS, the trailing slashes are silently stripped and a regular file named <tt>qwe</tt> is created instead. This behavior differs from POSIX expectations. | ||
<tt>EISDIR</tt> because trailing slashes imply a directory path. On HarmonyOS, | |||
the trailing slashes are silently stripped and a regular file named <tt>qwe</tt> | |||
is created instead. This behavior differs from POSIX expectations. | |||
'''Status:''' Not yet confirmed by Huawei.<br> | '''Status:''' Not yet confirmed by Huawei.<br>'''Reference:''' [https://bugreports.qt.io/browse/QTBUG-146578 QTBUG-146578] | ||
'''Reference:''' [https://bugreports.qt.io/browse/QTBUG-146578 QTBUG-146578] | |||
=== fread() incorrectly sets EOF on a non-blocking pipe === | === fread() incorrectly sets EOF on a non-blocking pipe === | ||
When <tt>fread()</tt> is called on a non-blocking pipe file descriptor with no | When <tt>fread()</tt> is called on a non-blocking pipe file descriptor with no data available, the HarmonyOS libc incorrectly sets the <tt>EOF</tt> flag on the <tt>FILE*</tt> stream. | ||
data available, the HarmonyOS libc incorrectly sets the <tt>EOF</tt> flag on | |||
the <tt>FILE*</tt> stream. | |||
'''Status:''' Not yet confirmed by Huawei.<br> | '''Status:''' Not yet confirmed by Huawei.<br>'''Reference:''' [https://bugreports.qt.io/browse/QTBUG-146579 QTBUG-146579] | ||
'''Reference:''' [https://bugreports.qt.io/browse/QTBUG-146579 QTBUG-146579] | |||
== Time and TimeZone == | |||
=== No tzdata available === | |||
HarmonyOS doesn’t provide /usr/share/zoneinfo.tab and the whole set files, we can’t use tz backend. | |||
Huawei's analysis: | |||
<blockquote>System musl libc has access to tzdata, but HarmonyOS doesn’t allow other 3rdparty to read tzdata directly.</blockquote> | |||
'''Status:''' Acknowledged by Huawei. Fix timeline unknown.<br> | |||
'''Workaround:''' Use icu backend for timezone.<br> | |||
'''Reference:''' [https://bugreports.qt.io/browse/QTBUG-146717 QTBUG-146717] [https://bugreports.qt.io/browse/QTBUG-146559 QTBUG-146559] | |||
== Thread == | |||
=== PTHREAD_CANCEL_DISABLE defined, but no related pthread functions available === | |||
PTHREAD_CANCEL_DISABLE defined, but no related pthread functions available | |||
'''Status:''' Acknowledged by Huawei. Fix timeline unknown.<br> | |||
'''Workaround:''' Undefine PTHREAD_CANCEL_DISABLE.<br> | |||
'''Reference:''' [https://bugreports.qt.io/browse/QTBUG-146708 QTBUG-146708] | |||
== Dynamic Linking == | == Dynamic Linking == | ||
=== MUSL-LDSO cannot load section-header-stripped ELF files === | === MUSL-LDSO cannot load section-header-stripped ELF files === | ||
The HarmonyOS MUSL dynamic linker fails to load ELF shared libraries from which | The HarmonyOS MUSL dynamic linker fails to load ELF shared libraries from which the section header table has been stripped. The linker internally depends on <tt>e_shnum</tt> and <tt>e_shoff</tt> fields within the <tt>LOAD_ORDER_RANDOMIZATION</tt> macro and cannot process binaries that omit the section header. | ||
the section header table has been stripped. The linker internally depends on | |||
<tt>e_shnum</tt> and <tt>e_shoff</tt> fields within the | |||
<tt>LOAD_ORDER_RANDOMIZATION</tt> macro and cannot process binaries that omit | |||
the section header. | |||
Huawei's analysis: | Huawei's analysis: | ||
<blockquote>Whether these dependencies can be eliminated in the future | <blockquote>Whether these dependencies can be eliminated in the future is still under investigation.</blockquote> | ||
is still under investigation.</blockquote> | |||
'''Status:''' Acknowledged by Huawei. Fix timeline unknown.<br> | '''Status:''' Acknowledged by Huawei. Fix timeline unknown.<br>'''Reference:''' [https://bugreports.qt.io/browse/QTBUG-146620 QTBUG-146620] | ||
'''Reference:''' [https://bugreports.qt.io/browse/QTBUG-146620 QTBUG-146620] | |||
=== MUSL-LDSO namespace policy prevents dlopen() from writable paths === | === MUSL-LDSO namespace policy prevents dlopen() from writable paths === | ||
The HarmonyOS MUSL dynamic linker rejects <tt>dlopen()</tt> for any path under | The HarmonyOS MUSL dynamic linker rejects <tt>dlopen()</tt> for any path under <tt>/data/storage/el2/</tt>, including temporary directories and all paths returned by <tt>QStandardPaths::writableLocation()</tt> (<tt>AppDataLocation</tt>, <tt>AppConfigLocation</tt>, <tt>CacheLocation</tt>). All available namespaces (<tt>moduleNs_default</tt>, <tt>default</tt>, <tt>ndk</tt>) reject these paths with <tt>errno=22 (EINVAL)</tt>. | ||
<tt>/data/storage/el2/</tt>, including temporary directories and all paths | |||
returned by <tt>QStandardPaths::writableLocation()</tt> | |||
(<tt>AppDataLocation</tt>, <tt>AppConfigLocation</tt>, <tt>CacheLocation</tt>). | |||
All available namespaces (<tt>moduleNs_default</tt>, <tt>default</tt>, | |||
<tt>ndk</tt>) reject these paths with <tt>errno=22 (EINVAL)</tt>. | |||
The only paths accessible to <tt>dlopen()</tt> reside under | The only paths accessible to <tt>dlopen()</tt> reside under <tt>/data/storage/el1/</tt>, which is read-only at runtime. | ||
<tt>/data/storage/el1/</tt>, which is read-only at runtime. | |||
'''Status:''' Not yet confirmed by Huawei.<br> | '''Status:''' Not yet confirmed by Huawei.<br>'''Reference:''' [https://bugreports.qt.io/browse/QTBUG-146624 QTBUG-146624] | ||
'''Reference:''' [https://bugreports.qt.io/browse/QTBUG-146624 QTBUG-146624] | |||
== Standard Paths == | == Standard Paths == | ||
=== QStandardPaths constraints on HarmonyOS === | === QStandardPaths constraints on HarmonyOS === | ||
The HarmonyOS application sandbox imposes several constraints on | The HarmonyOS application sandbox imposes several constraints on <tt>QStandardPaths</tt>: | ||
<tt>QStandardPaths</tt>: | |||
* <tt>standardLocations()</tt> and <tt>writableLocation()</tt> return identical single-path results for all location types, since the sandbox does not expose multiple search locations. | |||
* <tt>AppLocalDataLocation</tt> maps to HarmonyOS <tt>preferencesDir</tt>. | * <tt>AppLocalDataLocation</tt> maps to HarmonyOS <tt>preferencesDir</tt>. | ||
* The following location types are unsupported and return an empty path: | * The following location types are unsupported and return an empty path: | ||
<tt>PublicShareLocation</tt>, <tt>TemplatesLocation</tt>, | <tt>PublicShareLocation</tt>, <tt>TemplatesLocation</tt>, | ||
<tt>StateLocation</tt>, <tt>GenericStateLocation</tt>. | <tt>StateLocation</tt>, <tt>GenericStateLocation</tt>. | ||
* <tt>QStandardPaths::findExecutable()</tt> cannot locate system executables | * <tt>QStandardPaths::findExecutable()</tt> cannot locate system executables due to the <tt>stat()</tt> restriction described above. | ||
'''Status:''' Not yet confirmed by Huawei.<br>'''Reference:''' [https://bugreports.qt.io/browse/QTBUG-146625 QTBUG-146625] | |||
'''Status:''' | |||
'''Reference:''' [https://bugreports.qt.io/browse/QTBUG-146625 QTBUG-146625] | |||
=== Application resource directory location === | === Application resource directory location === | ||
On HarmonyOS, an application's bundled read-only resource directory resides at | On HarmonyOS, an application's bundled read-only resource directory resides at <tt><bundleCodeDir>/entry/resources/resfile</tt>. This is the appropriate location for bundled resources such as <tt>.rcc</tt> files. | ||
<tt><bundleCodeDir>/entry/resources/resfile</tt>. This is the appropriate | |||
location for bundled resources such as <tt>.rcc</tt> files. | |||
No <tt>QStandardPaths::StandardLocation</tt> currently maps to this path. | No <tt>QStandardPaths::StandardLocation</tt> currently maps to this path. | ||
'''Status:''' | '''Status:''' Not yet confirmed by Huawei.<br>'''Reference:''' [https://bugreports.qt.io/browse/QTBUG-146626 QTBUG-146626] | ||
'''Reference:''' [https://bugreports.qt.io/browse/QTBUG-146626 QTBUG-146626] | |||
== Font System == | == Font System == | ||
=== No fixed-pitch (monospaced) font provided by default === | === No fixed-pitch (monospaced) font provided by default === | ||
HarmonyOS does not ship a monospaced (fixed-pitch) system font by default. | HarmonyOS does not ship a monospaced (fixed-pitch) system font by default. <tt>QFontDatabase::systemFont(QFontDatabase::FixedFont)</tt> returns a non-monospaced font as a result. | ||
<tt>QFontDatabase::systemFont(QFontDatabase::FixedFont)</tt> returns a | |||
non-monospaced font as a result. | |||
Huawei confirmed that <tt>NotoSansMono</tt> must be installed by the user | Huawei confirmed that <tt>NotoSansMono</tt> must be installed by the user and is not included in the system font set. | ||
and is not included in the system font set. | |||
'''Status:''' Confirmed by Huawei.<br> | '''Status:''' Confirmed by Huawei.<br>'''Impact:''' Applications requiring a monospaced font must bundle and register one explicitly via <tt>QFontDatabase::addApplicationFont()</tt>.<br>'''Reference:''' [https://bugreports.qt.io/browse/QTBUG-146623 QTBUG-146623] | ||
'''Impact:''' Applications requiring a monospaced font must bundle and register one | |||
explicitly via <tt>QFontDatabase::addApplicationFont()</tt>.<br> | |||
'''Reference:''' [https://bugreports.qt.io/browse/QTBUG-146623 QTBUG-146623] | |||
== ArkUI / ArkTS API == | == ArkUI / ArkTS API == | ||
=== XComponentType.NODE deprecated in API version 20 === | === XComponentType.NODE deprecated in API version 20 === | ||
<tt>XComponentType.NODE</tt>, which Qt for HarmonyOS uses as the native rendering | <tt>XComponentType.NODE</tt>, which Qt for HarmonyOS uses as the native rendering surface, has been deprecated since HarmonyOS API version 20. Huawei recommends migrating to the <tt>ContentSlot</tt> component. | ||
surface, has been deprecated since HarmonyOS API version 20. Huawei recommends | |||
migrating to the <tt>ContentSlot</tt> component. | |||
No official porting guide has been provided by Huawei. Relevant documentation: | No official porting guide has been provided by Huawei. Relevant documentation: | ||
| Line 158: | Line 119: | ||
* [https://developer.huawei.com/consumer/en/doc/harmonyos-guides/arkts-rendering-control-contentslot ContentSlot: Enabling Hybrid Development] | * [https://developer.huawei.com/consumer/en/doc/harmonyos-guides/arkts-rendering-control-contentslot ContentSlot: Enabling Hybrid Development] | ||
'''Status:''' API deprecated by Huawei.<br> | '''Status:''' API deprecated by Huawei.<br>'''Impact:''' <tt>XComponentType.NODE</tt> remains functional in current API versions. Migration to <tt>ContentSlot</tt> is required before the deprecated API is removed.<br>'''Reference:''' [https://bugreports.qt.io/browse/QTBUG-146622 QTBUG-146622] | ||
'''Impact:''' <tt>XComponentType.NODE</tt> remains functional in current API | |||
versions. Migration to <tt>ContentSlot</tt> is required before the deprecated | == Clipboard == | ||
API is removed.<br> | |||
'''Reference:''' [https://bugreports.qt.io/browse/QTBUG-146622 QTBUG-146622] | === Pasteboard invokes the record provider prematurely when a record has no directly-added entry === | ||
The pasteboard supports paste-on-demand (lazy fetch) by registering a provider callback on a record via <tt>OH_UdmfRecord_SetProvider()</tt>. The provider is expected to be invoked only when a consumer actually requests data for a specific entry type. However, when a record is built with a registered provider but no directly-added entry, calling <tt>OH_Pasteboard_GetData()</tt> invokes the provider callback as a side effect — for the record's first registered type — before any consumer has requested that entry. This defeats lazy fetch: the data is materialized immediately when the clipboard is read, rather than on an actual paste. | |||
A record that carries at least one directly-added entry (alongside a provider for the remaining types) does not exhibit this behavior, and lazy fetch works as intended. | |||
Huawei's analysis:<blockquote>When <tt>OH_Pasteboard_GetData</tt> is called, the platform clipboard traverses each record and checks the first entry of the record. If the first entry has no actual data (provider path), the platform calls the provider once and then stores the returned data in the platform-side cache.</blockquote> | |||
'''Status:''' Confirmed by Huawei. Behavior is undocumented in the public C API.<br> | |||
'''Impact:''' For any record served entirely through the provider path (no concrete first entry), paste-on-demand is silently broken — the application's data is fetched eagerly when the clipboard contents are read instead of on paste.<br> | |||
'''Workaround:''' Ensure every record carries at least one directly-added ("dummy") entry so that no record is ever provider-only. The injected entry must be kept transparent to the application-visible data model.<br> | |||
'''Reference:''' [https://bugreports.qt.io/browse/QTBUG-147819 QTBUG-147819] | |||
== See Also == | == See Also == | ||
* [[ | * [https://developer.huawei.com/consumer/en/doc/harmonyos-references/musl-peculiar-symbol Huawei Doc: Native API Symbols Not Exported] | ||
* [[Qt for HarmonyOS]] | |||
* [[Building_Qt_for_HarmonyOS|Building Qt for HarmonyOS]] | * [[Building_Qt_for_HarmonyOS|Building Qt for HarmonyOS]] | ||
* [https://bugreports.qt.io/issues/?jql=project%20%3D%20QTBUG%20AND%20parent%20%3D%20QTBUG-146618 QTBUG-146618: HarmonyOS platform limitations (all child issues)] | * [https://bugreports.qt.io/issues/?jql=project%20%3D%20QTBUG%20AND%20parent%20%3D%20QTBUG-146618 QTBUG-146618: HarmonyOS platform limitations (all child issues)] | ||
Latest revision as of 12:26, 29 June 2026
This page documents known platform limitations of HarmonyOS that affect Qt behavior. These limitations stem from HarmonyOS security policies, missing system features, or deprecated APIs. Each entry includes its confirmation status and a reference to the corresponding public bug report.
Some items below are still under verification with Huawei and may be refined as more information becomes available.
File System & Permissions
chmod() / QFile::setPermissions() not supported
The HarmonyOS security model does not permit chmod() or fchmod() on existing files. As a result, QFile::setPermissions() is not supported on HarmonyOS for existing files and always returns false.
Note that operations that set permissions on a freshly created file descriptor — for example QFile::copy(), which uses fchmod() internally on the newly created destination — are unaffected.
Huawei's official response:
Due to security concerns, the system review for this interface was cancelled, and there is no alternative interface.
Status: Confirmed by Huawei.
Impact: QFile::setPermissions() is a no-op on HarmonyOS for existing files.
Reference: QTBUG-146619
symlink() not available for third-party applications
::symlink() and its ArkTS equivalent fs.symlink are unavailable to third-party applications on HarmonyOS. QFile::link() and any functionality depending on symbolic links will fail with EACCES (error code 13900012).
Huawei's official response:
fs.symlink is currently not available for third-party applications. The official documentation will be updated accordingly.
Status: Confirmed by Huawei.
Workaround: None available at this time.
Reference: QTBUG-146621
stat() returns EACCES on system paths
stat() returns EACCES (errno 13) when called on system paths such as /bin/sh on HarmonyOS. This causes QFileInfo::isFile() to return false for system executables, while QFileInfo::exists() and QFileInfo::isExecutable() (which use access() internally) return true.
As a consequence, QStandardPaths::findExecutable() cannot locate system executables on HarmonyOS.
Status: Not yet confirmed by Huawei.
Reference: QTBUG-146625
open() with trailing slashes does not fail as expected
On Linux, open("qwe//", O_RDWR|O_CREAT|O_CLOEXEC, 0666) fails with EISDIR because trailing slashes imply a directory path. On HarmonyOS, the trailing slashes are silently stripped and a regular file named qwe is created instead. This behavior differs from POSIX expectations.
Status: Not yet confirmed by Huawei.
Reference: QTBUG-146578
fread() incorrectly sets EOF on a non-blocking pipe
When fread() is called on a non-blocking pipe file descriptor with no data available, the HarmonyOS libc incorrectly sets the EOF flag on the FILE* stream.
Status: Not yet confirmed by Huawei.
Reference: QTBUG-146579
Time and TimeZone
No tzdata available
HarmonyOS doesn’t provide /usr/share/zoneinfo.tab and the whole set files, we can’t use tz backend.
Huawei's analysis:
System musl libc has access to tzdata, but HarmonyOS doesn’t allow other 3rdparty to read tzdata directly.
Status: Acknowledged by Huawei. Fix timeline unknown.
Workaround: Use icu backend for timezone.
Reference: QTBUG-146717 QTBUG-146559
Thread
PTHREAD_CANCEL_DISABLE defined, but no related pthread functions available
Status: Acknowledged by Huawei. Fix timeline unknown.
Workaround: Undefine PTHREAD_CANCEL_DISABLE.
Reference: QTBUG-146708
Dynamic Linking
MUSL-LDSO cannot load section-header-stripped ELF files
The HarmonyOS MUSL dynamic linker fails to load ELF shared libraries from which the section header table has been stripped. The linker internally depends on e_shnum and e_shoff fields within the LOAD_ORDER_RANDOMIZATION macro and cannot process binaries that omit the section header.
Huawei's analysis:
Whether these dependencies can be eliminated in the future is still under investigation.
Status: Acknowledged by Huawei. Fix timeline unknown.
Reference: QTBUG-146620
MUSL-LDSO namespace policy prevents dlopen() from writable paths
The HarmonyOS MUSL dynamic linker rejects dlopen() for any path under /data/storage/el2/, including temporary directories and all paths returned by QStandardPaths::writableLocation() (AppDataLocation, AppConfigLocation, CacheLocation). All available namespaces (moduleNs_default, default, ndk) reject these paths with errno=22 (EINVAL).
The only paths accessible to dlopen() reside under /data/storage/el1/, which is read-only at runtime.
Status: Not yet confirmed by Huawei.
Reference: QTBUG-146624
Standard Paths
QStandardPaths constraints on HarmonyOS
The HarmonyOS application sandbox imposes several constraints on QStandardPaths:
- standardLocations() and writableLocation() return identical single-path results for all location types, since the sandbox does not expose multiple search locations.
- AppLocalDataLocation maps to HarmonyOS preferencesDir.
- The following location types are unsupported and return an empty path:
PublicShareLocation, TemplatesLocation, StateLocation, GenericStateLocation.
- QStandardPaths::findExecutable() cannot locate system executables due to the stat() restriction described above.
Status: Not yet confirmed by Huawei.
Reference: QTBUG-146625
Application resource directory location
On HarmonyOS, an application's bundled read-only resource directory resides at <bundleCodeDir>/entry/resources/resfile. This is the appropriate location for bundled resources such as .rcc files.
No QStandardPaths::StandardLocation currently maps to this path.
Status: Not yet confirmed by Huawei.
Reference: QTBUG-146626
Font System
No fixed-pitch (monospaced) font provided by default
HarmonyOS does not ship a monospaced (fixed-pitch) system font by default. QFontDatabase::systemFont(QFontDatabase::FixedFont) returns a non-monospaced font as a result.
Huawei confirmed that NotoSansMono must be installed by the user and is not included in the system font set.
Status: Confirmed by Huawei.
Impact: Applications requiring a monospaced font must bundle and register one explicitly via QFontDatabase::addApplicationFont().
Reference: QTBUG-146623
ArkUI / ArkTS API
XComponentType.NODE deprecated in API version 20
XComponentType.NODE, which Qt for HarmonyOS uses as the native rendering surface, has been deprecated since HarmonyOS API version 20. Huawei recommends migrating to the ContentSlot component.
No official porting guide has been provided by Huawei. Relevant documentation:
Status: API deprecated by Huawei.
Impact: XComponentType.NODE remains functional in current API versions. Migration to ContentSlot is required before the deprecated API is removed.
Reference: QTBUG-146622
Clipboard
Pasteboard invokes the record provider prematurely when a record has no directly-added entry
The pasteboard supports paste-on-demand (lazy fetch) by registering a provider callback on a record via OH_UdmfRecord_SetProvider(). The provider is expected to be invoked only when a consumer actually requests data for a specific entry type. However, when a record is built with a registered provider but no directly-added entry, calling OH_Pasteboard_GetData() invokes the provider callback as a side effect — for the record's first registered type — before any consumer has requested that entry. This defeats lazy fetch: the data is materialized immediately when the clipboard is read, rather than on an actual paste.
A record that carries at least one directly-added entry (alongside a provider for the remaining types) does not exhibit this behavior, and lazy fetch works as intended.
Huawei's analysis:
When OH_Pasteboard_GetData is called, the platform clipboard traverses each record and checks the first entry of the record. If the first entry has no actual data (provider path), the platform calls the provider once and then stores the returned data in the platform-side cache.
Status: Confirmed by Huawei. Behavior is undocumented in the public C API.
Impact: For any record served entirely through the provider path (no concrete first entry), paste-on-demand is silently broken — the application's data is fetched eagerly when the clipboard contents are read instead of on paste.
Workaround: Ensure every record carries at least one directly-added ("dummy") entry so that no record is ever provider-only. The injected entry must be kept transparent to the application-visible data model.
Reference: QTBUG-147819