Commit Graph

41 Commits

Author SHA1 Message Date
Tarja Sundqvist 4c16c8afb3 Update commercial SPDX-License-Identifier
Some files in tqtc-qtbase were missing the commercial
SPDX-License-Identifier. Build files, examples, tests, or
documentation are not updated.

Task-number: QTQAINFRA-5900
Change-Id: I28b9c03a0e62f2b2ce1c9edbe13921f4146a0924
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
(cherry picked from commit ffb7d2e320)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2023-12-11 20:15:27 +00:00
Piotr Wierciński d90692ce96 wasm: Backport support for child windows
Backport support for child windows on WASM. The main source of changes
is commit fc4fca6d9d.

Fixes: QTBUG-117897
Change-Id: Iaf1016e32581c2c138d5a4dceb3c050aa88cc636
Reviewed-by: Morten Johan Sørvig <morten.sorvig@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Piotr Wierciński <piotr.wiercinski@qt.io>
2023-11-02 13:56:52 +02:00
Mikolaj Boc 369f075471 Transfer touch event handling to QWasmWindow
Fixes: QTBUG-103498
Change-Id: Iec8b5cfba75131e7ddf855e6b729291950888fd3
Reviewed-by: Lorn Potter <lorn.potter@gmail.com>
Reviewed-by: Aleksandr Reviakin <aleksandr.reviakin@qt.io>
(cherry picked from commit da5dc20625)
Reviewed-by: Mikołaj Boc <Mikolaj.Boc@qt.io>
2023-03-28 17:44:25 +01:00
Mikolaj Boc 52c3209ce9 Transfer the key handling logic to QWasmWindow
Also, use the embind approach as the rest of the events do, and
introduce a KeyEvent class which simplifies and streamlines event
support.

The event translator has been given a more specific function of
just handling the dead keys. Rest of the translation functionality
is coded directly in KeyEvent for more encapsulation.

Change-Id: I11b0262fc42fe920206ecc6de0d434b9d9ab9998
Reviewed-by: Morten Johan Sørvig <morten.sorvig@qt.io>
(cherry picked from commit d141d68949)
Reviewed-by: Mikołaj Boc <Mikolaj.Boc@qt.io>
2023-03-27 19:11:45 +01:00
Mikolaj Boc fc116c650e Remove dead code from QWasmCompositor
Some of the fields and functions are not used now. Remove those.

Change-Id: I9313eee37374d82de2a1982a54843a70c58af426
Reviewed-by: Morten Johan Sørvig <morten.sorvig@qt.io>
(cherry picked from commit 1737dfa34a)
Reviewed-by: Mikołaj Boc <Mikolaj.Boc@qt.io>
2023-03-23 15:34:14 +01:00
Mikolaj Boc a8fe4c1efb Handle the wheel event in the wasm window
Align the wheel event handling with other events - move the handler to
wasm window and create a C++ wrapper class for the js wheel event.

Fixes: QTBUG-109622
Change-Id: I915e502de7c0784ec9a6745a90ddcda062e91b2b
Reviewed-by: Mikołaj Boc <Mikolaj.Boc@qt.io>
Reviewed-by: Lorn Potter <lorn.potter@gmail.com>
Reviewed-by: Morten Johan Sørvig <morten.sorvig@qt.io>
(cherry picked from commit c54416a06c)
2023-03-22 16:04:46 +01:00
Mikolaj Boc 6501b85d38 Handle the mouse events in the window itself
It is now not the screen that handles all of the events and relays
them to individual windows, but the window elements themselves.

This allows us to get rid of manual window targeting logic and let
the browser do its job.

Fixes: QTBUG-107217
Change-Id: I4dc5a74b1343f027f72c1da4623b99cd28bfbb38
Reviewed-by: Morten Johan Sørvig <morten.sorvig@qt.io>
(cherry picked from commit c15a8750bc)
Reviewed-by: Mikołaj Boc <Mikolaj.Boc@qt.io>
2023-01-14 18:29:24 +01:00
Mikolaj Boc c613c5ce22 Return to the two-step destruction in compositor
The two-step destruction we used to employ is needed as destroying
a screen which contains a window crashes.

Change-Id: I722828be5408a7f079d66e845eeee34ed19cbf34
Reviewed-by: Lorn Potter <lorn.potter@gmail.com>
(cherry picked from commit 644036b597)
Reviewed-by: Morten Johan Sørvig <morten.sorvig@qt.io>
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2023-01-13 14:49:15 +01:00
Mikolaj Boc 33895a9b6d Move the window through the title bar element itself
The compositor is redundant in the process of moving the window.
Have the title bar react to move all by itself.

Additionally, a clearer structure in the window was introduced.
The non-client area has been extracted into a separate class, as
was the icon store and free DOM functions used across files.

Since it was now easy, made the window maximize/restore on double click
on the title element.

Fixes: QTBUG-107626
Change-Id: Iba7f207e46806ae7162656965892ae5a48ac5ebe
Reviewed-by: Morten Johan Sørvig <morten.sorvig@qt.io>
(cherry picked from commit 32666691c2)
Reviewed-by: Mikołaj Boc <Mikolaj.Boc@qt.io>
2023-01-13 14:49:14 +01:00
Mikolaj Boc e50bc60e87 Resize wasm windows using a div outline
Introducing a div outline which handles the resize events by itself.
Manual computations in wasm compositor are no longer needed.

The outline reacts to setting css variables (border-width,
resize-outline-width), it sets the correct cursors using css and
always keeps the correct size.

Fixes: QTBUG-107498
Change-Id: I6b0564632af5e17e464fe93a3dfa20820c624292
Reviewed-by: Morten Johan Sørvig <morten.sorvig@qt.io>
2022-12-05 22:26:59 +01:00
Mikolaj Boc a812d1eb66 Don't tie compositor's enabled state to last added window
Currently, the compositor gets enabled/disabled based on the last
constructed window's surface type. This causes non-OpenGL windows not to
be displayed if any OpenGL window is created last.

The compositor should scan for any non-openGL windows on any change
to the window set to decide if it needs to be disabled or not.

Change-Id: I037470e39a3fbae50fd3a4e29cb6615130d7b114
Reviewed-by: Morten Johan Sørvig <morten.sorvig@qt.io>
2022-11-30 20:05:10 +01:00
Mikolaj Boc fa27a59ec3 Use the browser compositor for drawing windows on WASM
Make the browser compositor draw the window non-client area (using css
+ html). Get rid of OpenGL usage in non-OpenGL windows and use canvas
2d context instead to blit the texture (QImage).

Also, as part of the change, remove the deprecated canvas element support
in QScreen.

Fixes: QTBUG-107116
Fixes: QTBUG-107219
Change-Id: I65f0d91831c806315685ca681ac0e416673f5cd5
Reviewed-by: Morten Johan Sørvig <morten.sorvig@qt.io>
Reviewed-by: Aleksandr Reviakin <aleksandr.reviakin@qt.io>
Reviewed-by: David Skoland <david.skoland@qt.io>
2022-11-26 11:23:13 +01:00
Mikolaj Boc fffea48ea5 Fix typo in QWasmWindowStack's name
'Wasm' in it is duplicated.

Change-Id: Ie00e02fb7ae4d9e13f490ce2d46a4eabf3f5710c
Reviewed-by: Lorn Potter <lorn.potter@gmail.com>
2022-10-20 16:36:23 +02:00
Mikolaj Boc 9bf689e875 Remove dead code & cull public API in WASM compositor
- Remove the manual destroy methods - destructor should handle
destruction
- Remove the unused enum QWasmStateFlag
- Make public API private where possible
- Adjust handleTouch->processTouch to keep consistency with other
process methods
- Remove dead fields in compositor
- Don't keep a dead screen entry in m_screens in qwasmintegration

Change-Id: I98caf4dbdda5ebd25c4a9c22a40140c7ed1d7aa7
Reviewed-by: Morten Johan Sørvig <morten.sorvig@qt.io>
2022-10-05 00:36:41 +02:00
Mikolaj Boc de56047620 Redirect resize from QSizeGrip to system resize in wasm compositor
Using two different resizing techniques (one in QSizeGrip, one in
QWasmCompositor) leads to strange behavior while resizing wasm windows.
Redirect the QSizeGrip's resize to wasm's compositor resize (which might
be considered system resize) to avoid that.

Change-Id: Idfc062643caac3ceee879bfb875d943aade28378
Reviewed-by: David Skoland <david.skoland@qt.io>
Reviewed-by: Morten Johan Sørvig <morten.sorvig@qt.io>
2022-09-20 16:34:57 +02:00
Morten Sørvig be44827240 wasm: add support for building Qt as shared libraries
This implements the build system bits required to build Qt
as as separate wasm modules a.k.a Emscripten side modules.

Enable by configuring with the "-shared" flag.

This is the first step towards shared library support and gets
us as far as being able to load QtCore and instantiate a
QCoreApplication.

Task-number: QTBUG-63925
Change-Id: Ib8f07f80fb5b13c8dbba65c7db735dc557b70d0e
Reviewed-by: Morten Johan Sørvig <morten.sorvig@qt.io>
2022-08-30 22:11:01 +10:00
Mikolaj Boc f35e5a44b0 Implement mouse capture on WASM
This fixes dock widget undocking - previously, without the capture, any
widget that the mouse accidentally entered would get the event,
resulting in re-docking problems, cursor issues etc.

Fixes: QTBUG-105621
Pick-to: 6.4
Change-Id: Ia1f2c91578018f2ae9df903bc0730200ede17d32
Reviewed-by: Lorn Potter <lorn.potter@gmail.com>
2022-08-27 00:10:34 +02:00
Mikolaj Boc 6cd0dc213b Move titlebar drawing routines to QWasmWindow
The title bar drawing routines belong in QWasmWindow, not in the
compositor. This provides better encapsulation as many properties
don't have to be leaked from QWasmWindow. Extensibility will also
improve.

Change-Id: If73dd4e87602f62bff0de92e1405f89e7a9f3b43
Pick-to: 6.4
Reviewed-by: Morten Johan Sørvig <morten.sorvig@qt.io>
2022-08-25 16:53:47 +02:00
Mikolaj Boc 906dfef22b Use the qt type Qt::Edges instead of wasm-specific
The types essentially do the same job - the one that is more general
should be used, the other - removed, as it is redundant.

Change-Id: Iec09d3311681abce1405fcf8c2cebfb72f3fd51c
Reviewed-by: Lorn Potter <lorn.potter@gmail.com>
2022-08-24 21:12:00 +02:00
Mikolaj Boc 11f12521bc Resolve window focusing problems on WASM
- Moved the modal window resolution to
QWasmWindow::requestActivateWindow so that multiple async activation
events are not issued in unpredictable patterns.
- Request activation on added windows and on stack top in case of
window removal

Pick-to: 6.4
Change-Id: I6f02cf1b7e83abb7961caf311ffc83e91c8bf810
Reviewed-by: Morten Johan Sørvig <morten.sorvig@qt.io>
2022-08-24 17:50:25 +02:00
Mikolaj Boc 80d9436488 Remove the dead drawShadePanel in qwasmcompositor
The method is not used anywhere. Remove it to save tens of LOCs.

Change-Id: Id853d12d238aa30eb197ab3fed7ccc24a2213e31
Pick-to: 6.4
Reviewed-by: Morten Johan Sørvig <morten.sorvig@qt.io>
2022-08-23 18:49:47 +00:00
Mikolaj Boc 1007964f2d Maintain the window z-order properly in wasm compositor
The old stack structure used to keep track of windows has been improved
to conform to the actual windowing assumptions: there shall be one root
window, which is always at the bottom. The first created window
immediately becomes the root window. Should the root window be removed,
all windows are non-root, i.e. any of them can become the top-level window

Fixes: QTBUG-105094
Pick-to: 6.4
Change-Id: Ic553244fa9f5bc3ee590b702935e66cfc62d5f8f
Reviewed-by: Morten Johan Sørvig <morten.sorvig@qt.io>
2022-08-16 16:08:38 +00:00
Mikolaj Boc 4b165c6bcc Remove QWasmCompositedWindow as dead code
No fields in QWasmCompositedWindow, apart from visible, are used for any
computation. They were write-only. Remove the class entirely and create
a hash of visibility state instead.

Fixes for z-order will follow.

Change-Id: Icb7ff1865d1f9a67c0fde43cfa331ca1242ebcaa
Reviewed-by: Lorn Potter <lorn.potter@gmail.com>
2022-07-28 15:11:54 +02:00
Mikolaj Boc 19507dc678 Deliver non-client area mouse events to WASM windows
QWasmCompositor now delivers non-client area mouse events to windows as
it should, which fixes a lot of issues with window manipulation. One of
such issues is re-docking of dock widgets.

Fixes: QTBUG-105092
Change-Id: I9de45b7e1b1a80b64387031eb0cc0b31a4be2571
Reviewed-by: Lorn Potter <lorn.potter@gmail.com>
2022-07-27 14:08:08 +02:00
Mikolaj Boc 5a4e5c62af Improve window dragging on WASM
Window dragging has been considerably improved by replacing the mouse
events by pointer events and placing a pointer lock on WASM canvas, so
that off-browser window events are delivered to us.

Translation of the drag origin has been limited to inside the canvas, so
that a window cannot be dragged so far that it becomes offscreen and is
unreachable.

Change-Id: Id177c630a6466f04464a513371d6b97d3a098b6a
Reviewed-by: Lorn Potter <lorn.potter@gmail.com>
2022-07-25 14:40:40 +02:00
Mikolaj Boc ec58600cc9 Refactor code focused around QWasmCompositor::processMouse
Refactoring of the logic around QWasmCompositor::processMouse has been
performed for readability and easier modification, in preparation for
further fixes for event delivery and handling in windows. There should
be no logic changes, just cleaner code.

Change groups:
Members of QWasmCompositor have been prefixed by m_ for easier discerning
of stateful and stateless variables in functions.

Variables renamed to more descriptive, e.g. window2->targetWindow,
globalPoint->targetPointInScreenCoords.

Magic numbers eliminated, e.g. mouseEvent->button == 0 is now
button == Qt::MouseButton::LeftButton.

Some common condition checks have been wrapped into single constants,
e.g. !(htmlWindow->m_windowState & Qt::WindowFullScreen) &&
!(htmlWindow->m_windowState & Qt::WindowMaximized) ==
isTargetWindowResizable

Some nested if-conditions were collapsed.

Some unnecessary checks have been moved to outer if conditions (e.g. for
draggedWindow in EMSCRIPTEN_EVENT_MOUSEMOVE, since the code would crash
anyway because only some parts are guarded against it being nullptr).

Consts introduced so that variables are only used for one purpose.

Made QWasmEventTranslator::translateMouseButton constexpr

Made QWasmWindow::isPointOnTitle behave correctly when the window has
no title bar so that no flag probing is needed prior to calling it.

Made QWasmCursor::setOverrideWasmCursor accept a const ref - having it
accept pointer suggested it might dangle.

Change-Id: I8910622fddad764ee86eb0260b5ad23c7ee7f97a
Reviewed-by: David Skoland <david.skoland@qt.io>
2022-07-15 20:57:01 +02:00
Lucie Gérard 05fc3aef53 Use SPDX license identifiers
Replace the current license disclaimer in files by
a SPDX-License-Identifier.
Files that have to be modified by hand are modified.
License files are organized under LICENSES directory.

Task-number: QTBUG-67283
Change-Id: Id880c92784c40f3bbde861c0d93f58151c18b9f1
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
Reviewed-by: Jörg Bornemann <joerg.bornemann@qt.io>
2022-05-16 16:37:38 +02:00
Lorn Potter 852bb43605 wasm: fix window leave and enter events
Leave and enter events are not happening
when the mouse enters or leaves the browser
window/canvas.

Done-with: Alexandra Cherdantseva <neluhus.vagus@gmail.com>
Change-Id: I702584980c6bea6a36143281de658e566e4c155b
Pick-to: 6.3
Fixes: QTBUG-100950
Reviewed-by: Morten Johan Sørvig <morten.sorvig@qt.io>
2022-04-28 12:44:04 +10:00
Morten Johan Sørvig 4ff5a571b3 wasm: Support non-canvas container elements
Support specifying that Qt should use a div element
as the root container, in which case canvas management
is moved to Qt C++ code.

This enables us to take ownership of the canvas and its
configuration. In addition, it allows creating child
elements for the Qt container (canvas element children
have a special role are as fallback elements displayed
in case the browser can’t show the canvas)

Remove support for reading Module.canvas, which was
deprecated in Qt 5.

Add support for reading Module.qtContainerElements,
which can be either a canvas element (legacy) or a
div element (preferred).

Deprecate qtCanvasElements and print warning on usage.

Change QWasmScreen to accept either a canvas or any
html element. In the latter case, create the canvas
and configure it as required by Qt.

Change-Id: I57df8fb5772b2bfbba081af3f572b8b0e7d51897
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
2022-03-31 18:47:17 +02:00
Lorn Potter 66a76a5def wasm: enable mobile native keyboarding
This works on iOS and Android, and Windows with touchscreen.

On Android, we need to listen to the input event
of a hidden text element and synthesize Qt keyboard
events from that in order to get input events into Qt.

On Windows, we need to be more creative about bringing the native
virtual keyboard up.

Because the entire canvas is contenteditable, we need to specify the
inputmode is set to 'none', otherwise the v keyboard pops up
when user clicks anywhere on the canvas. Therefore we set a hidden
element as contenteditable, which pops up keyboard when Qt
needs it for editable widgets. On Android, this is the same
element that is used to proxy the keyboard input.

[ChangeLog][wasm] Add support for native mobile keyboard

Done-with: Morten Johan Sørvig <morten.sorvig@qt.io>
Fixes: QTBUG-83064
Fixes: QTBUG-88803
Change-Id: I769fe344fc10c17971bd1c0a603501040fe82653
Reviewed-by: David Skoland <david.skoland@qt.io>
Reviewed-by: Morten Johan Sørvig <morten.sorvig@qt.io>
2022-03-03 12:30:59 +10:00
David Skoland 5359d420af Move input event logic into QWasmCompositor
Move the window logic and state out of QWasmEventTranslator and into
QWasmCompositor.

The reasoning for this change is that the state of the windowing
system was split between QWasmCompositor (eg. window stack) and
QWasmEventTranslator (eg. dragged and pressed windows). This change
moves the input handling and state to QWasmCompositor and demotes
QWasmEventTranslator to a helper class. In this model, QWC acts
as a proper window system / display server and can leverage multiple
helper classes which are "owned" by the QWC.

Here is a quick diagram illustrating the proposed general architecture
around WASM window handling and its difference from typical OSes:
https://i.imgur.com/vcBwUPf.png

Change-Id: Idca617992b8e1b431e5c71d46b5db61597c99e75
Pick-to: 6.3
Reviewed-by: Morten Johan Sørvig <morten.sorvig@qt.io>
2022-01-17 18:23:50 +01:00
Morten Johan Sørvig eb62b6ac02 wasm: always use requestAnimationFrame for updates
The compositor was posting update events and flushing/redrawing
using a zero-timer. Change this to use the request_animation_frame
API from Emscripten, which makes sure we flush window
content at the next native paint event.

This has the additional benefit that hidden canvases
(e.g on hidden tabs) won’t get frame events, and then
stop painting.

We support both well-behaved QWindows, where the window
calls requestUpate() and then paints/flushes on the
following deliverUpdateRequest(), and also less well
behaved windows which paints at any point during event
processing.

Pick-to: 6.3
Change-Id: I747d6f7ace86ceddaa18ab86b6a0ee833f98991b
Reviewed-by: Lorn Potter <lorn.potter@gmail.com>
2022-01-05 21:25:38 +01:00
Morten Johan Sørvig fd0ef140cf wasm: make the compositor draw the window icon
Currently the compositor draws the Qt logo by default;
check if the window has an icon and draw that instead
if set.

Fixes: QTBUG-86052
Pick-to: 6.2
Change-Id: Ia4f9c03562c15993c86cb8717f27e47ab669353d





Reviewed-by: Lorn Potter <lorn.potter@gmail.com>
2021-12-06 14:42:45 +01:00
Lars Knoll a450cce6b6 Merge remote-tracking branch 'origin/5.15' into dev
Change-Id: I469b0501cc65fc5ce4d797a69ae89405cc69c7f8
2020-02-28 09:48:30 +01:00
Alexandra Cherdantseva 0efdf54a16 wasm: fix texture leak when window is destroyed in a different context
Reproduce:
Show first window in first canvas;
Show second window in second canvas;
After screens are rendered destroy first window in first canvas

Change-Id: Ifbeb4824c1fdedecf24d5d20e58613d15c066420
Reviewed-by: Morten Johan Sørvig <morten.sorvig@qt.io>
2020-02-27 01:53:57 +03:00
Johan Klokkhammer Helsing fcaa7506ba Move QOpenGLTextureBlitter from QtGui to QtOpenGL
Task-number: QTBUG-74409
Change-Id: Ie4a3dfd01ba44715de6da71c4420fe9a95a0c242
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Laszlo Agocs <laszlo.agocs@qt.io>
2020-02-04 18:02:41 +01:00
Johan Klokkhammer Helsing 2344e5cc31 Move QOpenGLTexture and related classes from QtGui to QtOpenGL
Task-number: QTBUG-74409
Change-Id: Ied825dd7cb92365505a4aa43fd67488024160341
Reviewed-by: Laszlo Agocs <laszlo.agocs@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
2020-01-24 08:57:38 +01:00
Morten Johan Sørvig c8c4819b7b wasm: controlled screen destruction
Freeing OpenGL resources requires a current context,
which (on wasm) requires a screen.

Add a destroy() functions to QWasmScreen, QWasmCompositor, QWasmWindow,
and QWasmBackingStore which facilitates OpenGL cleanup before we start
deleting screen objects.

Task-number: QTBUG-75463
Change-Id: I9954b536416b9147965c74459ccad838d1578778
Reviewed-by: Lorn Potter <lorn.potter@gmail.com>
2019-05-14 11:00:14 +00:00
Morten Johan Sørvig e227c33455 wasm: improve event coordinate handling
targetX and targetY are canvas-local coordinates,
while Qt generally works with window-local and global
coordinates.

Add coordinate mapping calls where needed and make
sure we pass correct coordinate types to Qt.

This starts mattering when we have canvases which
are not located at (0, 0).

Change-Id: I28563310ca17d0cc5535317cff99fcd82d3723db
Reviewed-by: Lorn Potter <lorn.potter@gmail.com>
2019-04-04 09:30:02 +00:00
Morten Johan Sørvig caa74f16d4 wasm: support rendering to multiple canvases
Qt (via the the qtloader.js API) now supports rendering
to multiple canvases. The application sees each canvas
as a QScreen.

Make qtloader.js support multiple canvases:

  var qtloader = QtLoader({
    canvasElements : [array-of-canvas],
    showCanvas: function() {
      // make canvas(es) visible
    },
 });

The canvases were previously created/returned by showCanvas(),
however this function is called after the Qt app has
been started and adding screens that that point is
too late. (This worked before since there was only one
screen, and no need to connect each screen instance
to specific canvas.)

Remove QWasmScreen, QWasmCompositor, and QWasmEventTranslator
singletons from QWasmIntegration. These are are now
crated per-screen and are owned by the QWasmScreen.

Task-number: QTBUG-64079
Change-Id: I24689929fd5bfb7ff0ba076f66937728fa4bc4e4
Reviewed-by: Lorn Potter <lorn.potter@gmail.com>
2019-03-08 10:09:57 +00:00
Morten Johan Sørvig 29c0377f07 WebAssembly for QtBase
This is the squashed diff from wip/webassembly to dev.

Done-with: Peng Wu <peng.wu@intopalo.com>
Done-with: Sami Enne <sami.enne@intopalo.com>
Done-with: Morten Johan Sørvig <morten.sorvig@qt.io>
Started-by: Andrew Knight <andrew.knight@intopalo.com>
Change-Id: I6562433c0a38d6ec49ab675e0f104f2665f3392d
Reviewed-by: Lorn Potter <lorn.potter@gmail.com>
Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>
2018-08-30 06:48:33 +00:00