aboutsummaryrefslogtreecommitdiffstats
Commit message (Collapse)AuthorAgeFilesLines
* Improve performance of animators.v5.4.0-beta1Gunnar Sletta2014-10-105-18/+63
| | | | | | | | | | | | | | | The use of one QCoreApp::postEvent() per completed animation added up to a very large overhead when 1000+ animators were used at the same time. This is very relevant for sprite games and similar and deserves to work at least as good as normal animations. Instead, store the animations to stop and stop then on the gui thread later as a result of frameSwapped. For the benchmark in question this allows for roughly double the amount of animators being started and stopped. Change-Id: Iae3d1ec1502ee1908fdbba708fa9f976aa230064 Reviewed-by: Michael Brasser <michael.brasser@live.com>
* Fix issues with Keyboard Focus documentation.Mitch Curtis2014-10-101-3/+3
| | | | | Change-Id: I0dcc364456404a761a555da065452a59d1249a2f Reviewed-by: Topi Reiniö <topi.reinio@digia.com>
* Stabilize and fix comparisons in animator tests.Gunnar Sletta2014-10-1011-64/+60
| | | | | | | | | | | | | compare() will compare properties of objects and neither Qt.rgba nor image.pixel created objects has enumeratable properties so compare is pretty much useless. Use verify + == which will rely on toString() which is ok. A few of the tests relied on execution order of signals emitted on animation.running being changed and would occasionally fail. Change-Id: I531c7f21b58a922a6be9ca2b6de120a68209a6d6 Reviewed-by: Michael Brasser <michael.brasser@live.com>
* PathView: Fix QML engine thinking currentItem is null when it's notSérgio Martins2014-10-103-0/+47
| | | | | | | | QML didn't re-evaluate any bindings using currentItem because a notification was missing. Change-Id: Icdaa3022e0b01644a060e577d87f011b4ea9fabb Reviewed-by: Alan Alpert <aalpert@blackberry.com>
* Fix QQmlExpression/QQmlScriptString/QQmlBinding crashesSimon Hausmann2014-10-0925-87/+87
| | | | | | | | | | | | | | | | | | | | | | | | In the QQmlScriptString we store the binding id and it is an index into the runtimeFunctions array of the compilation unit. However we don't store the compilation unit and instead in QQmlBinding and QQmlExpression try to retrieve it from the cache via the context url (we have the context after all). That turns out to be not a reliable way, as sometimes the URL might slightly differ from the originally compiled cache (qrc:/// turning to qrc:/ maybe). Consequently the type is (unnecessarily) compiled again and unfortunately not _linked_, therefore the runtime functions array is empty. Another option is that when the component was created from a QByteArray, then no entry exists in the cache in the first place. This patch addresses the problem by storing a reference to the compilation unit in the QQmlContextData. That we can safely retrieve and it'll make sure the compilation unit also stays alive. In the process of that the manual reference counting was switched over to QQmlRefCount and QQmlRefPointer for QV4::CompilationUnit. Task-number: QTBUG-41193 Change-Id: I9111f9a3b65618e453954abcd789c039e65a94f7 Reviewed-by: Lars Knoll <lars.knoll@digia.com>
* Return the content position rounded on the right sideGiulio Camuffo2014-10-091-9/+9
| | | | | | | | | | | | | | | | | | | QQuickFlickable::contentX/Y() returns the negative of the value stored in the QQuickTimeLineValue used by QQuickFlickable. So we must be careful when using things like qRound, and call it with the negative of the value ine the QQuickTimeLineValue, else code like this would fail: QQuickFlickable *f = ... f->setPixelAligned(true) f->setContentY(-10.5) assert(f->contentY() == qRound(-10.5)) // fail The assert expression indeed turns into -11 == -10, which is false but which is not what the user would expect. Change-Id: Ib92ee2fa613b751462237349d9e4e2f2b4652f82 Reviewed-by: Martin Jones <martin.jones@qinetic.com.au>
* Export QQuickKeyNavigationAttached as a part of the private APIOleg Shparber2014-10-091-1/+1
| | | | | | | | This change fixes linking problems when QQuickKeyNavigationAttached is used through private headers. Change-Id: I176a9551718d9ba25c160a3b1caa8872c88d39f3 Reviewed-by: Alan Alpert <aalpert@blackberry.com>
* Make QQuickKeyNavigationAttached respect user set valuesOleg Shparber2014-10-091-6/+6
| | | | | | | | | | Before this change, when user tried to set KeyNavigation property to the value which was previously automatically assigned, user set flag wasn't raised. Such behavior led to situations, when explicitly set values later were not respected by automatic mutual changes. Change-Id: Id5ba5061c03a61f4d7835a638dc746b1485b9a56 Reviewed-by: Alan Alpert <aalpert@blackberry.com>
* Doc: Updated the QML State Machine docsVenu2014-10-097-125/+111
| | | | | | | | | | | | | | - Excluded the src/imports/statemachine directory from qtquick.qdocconf to avoid unnecessary qdoc warnings. - corrected a broken link to an external source - changed the group name to avoid collision - added a \qmlmodule page for QtQml.StateMachine - Reduced the amount of duplication between the C++ and QML state machine overviews. Task-number: QTBUG-41561 Change-Id: I87c815fada7006f0609331e315bb338f062bb4db Reviewed-by: Topi Reiniö <topi.reinio@digia.com>
* Doc: Updated the \brief and detailed descriptionVenu2014-10-091-2/+3
| | | | | | | | | | Just to give a hint to the reader about what the example does. Task-number: QTBUG-37203 Change-Id: Ibb377e4adfb25ed4e4da0a41280e4157fae638ba Reviewed-by: Topi Reiniö <topi.reinio@digia.com> Reviewed-by: Leena Miettinen <riitta-leena.miettinen@digia.com>
* Fix memory leak and crash with transform animators.Gunnar Sletta2014-10-094-7/+95
| | | | | | | | | | | | | | | | | | Every time initialize() was called, we would increment the ref on an item. However, initialize is called every time the job is started, so the ref would increase and only decrease once, leading to a leaked helper. Change it to only increment the first time. A different problem was that when an item was destroyed, we could run the risk of the QQuickTransformAnimatorJob destructor being called with the helper's item being null. This would lead to the helper not being removed from the cache and a dangling helper would remain in the transforms cache. Now change it so that when a target is destroyed, we explicitly destroy the helper as well (as no animation can happen then anyway) and reset all pointers in the job. Change-Id: I1ce76db134bbc1871d32f1224ba5b68a4a4eeafa Reviewed-by: Michael Brasser <michael.brasser@live.com>
* Remove alpha channel from images that doesn't actually have alpha.Gunnar Sletta2014-10-091-0/+25
| | | | | | | | | We did this for QPixmap since forever, and it has a huge impact on rendering performance, so there is no reason why we shouldn't spend that extra bit of time. Change-Id: Ibd2e6d585525a5b5a975b8d7498c21dec00647c5 Reviewed-by: Laszlo Agocs <laszlo.agocs@digia.com>
* Compare doesn't work for colors, so compare the channels explcitily.Gunnar Sletta2014-10-091-1/+3
| | | | | Change-Id: I7a21328700c85b5b79dbb4342817e28833dece70 Reviewed-by: Laszlo Agocs <laszlo.agocs@digia.com>
* Relax ShaderEffectSource's sourceItem vs window handling.Gunnar Sletta2014-10-092-1/+87
| | | | | | | | | | | For dynamically loaded items, the window may not be set on either the source or the item, so we need to be a bit more relaxed in our checking. This fixes a regression for dynamically loaded GaussianBlur. Change-Id: I3e888405a95058ca79ecd2dff42c0ed4c8fff065 Reviewed-by: Laszlo Agocs <laszlo.agocs@digia.com>
* Fix missing glyphs in selectionEskil Abrahamsen Blomfeldt2014-10-093-27/+77
| | | | | | | | | | | | | | | | | Change 198009db79a85d3cab7fe3a6432635d36123a2d6 revealed a bug in the new selection algorithm which would occur sometimes when a given run of text spanned several script items. Since we are checking the glyph runs for overlaps in the actual text, we need to report the exact characters spanned by the glyph run. We use the new enabler for this in QGlyphRunPrivate. Added a new test case which is an error case we did not yet cover, which is when there is only a single script item, but several font engines are used to produce it (fallback fonts). Change-Id: Ie4c3e79ad98a033d5c75fd67ada4ae83df33435b Task-number: QTBUG-41808 Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
* Temporarily skip tst_qquickframebufferobject when using ANGLE.Friedemann Kleint2014-10-091-0/+4
| | | | | | | Task-number: QTBUG-41815 Change-Id: I5c6ec36a4f8830d95e1d4904d1be41d752757339 Reviewed-by: Andrew Knight <andrew.knight@digia.com> Reviewed-by: Gunnar Sletta <gunnar@sletta.org>
* QQuickWindow autotest: focus transferred to parent on window closeShawn Rutledge2014-10-091-3/+0
| | | | | | | | | | | These bugs were fixed so XFAIL is no longer necessary in the autotest (change da0c74550f0e8a21239896d6aead6e05f85eb695 in qtbase). Task-number: QTBUG-33423 Task-number: QTBUG-39809 Change-Id: Ia89554b9f54aca7ef6c6ac6b474ca2bb9c0f5629 Reviewed-by: Jani Heikkinen <jani.heikkinen@digia.com> Reviewed-by: J-P Nurmi <jpnurmi@theqtcompany.com>
* Prevent removeFirst call on empty list.Zeno Endemann2014-10-011-2/+2
| | | | | | | | | The hoverItems list might get changed as a result of the sendHoverEvent call, so it is safer to take the element out first. Change-Id: I88c7380a2e4dd2297f9d0cfe01edc453ca525cb3 Reviewed-by: Jan Arne Petersen <jan.petersen@kdab.com> Reviewed-by: Gunnar Sletta <gunnar@sletta.org>
* use the new form of QTranslator::load() for more flexibilityShawn Rutledge2014-10-014-13/+16
| | | | | | | | | | | | | | As the docs explain, the variant of QTranslator::load() taking a const QLocale& is better because it "uses QLocale::uiLanguages() and not simply the locale name, which refers to the formatting of dates and numbers and not necessarily the UI language." And, using a default-constructed QLocale permits QLocale::setDefault() to override the system locale, so for example an application's main.cpp can do that before constructing a QQmlApplicationEngine. Task-number: QTBUG-7329 Change-Id: Ia29a4c894087c92b071c0fe484728866f2660fe6 Reviewed-by: Jan Arve Sæther <jan-arve.saether@digia.com>
* documentation for qmldir "depends" declarationShawn Rutledge2014-10-011-0/+19
| | | | | | | | | | [ChangeLog][QtQml][qmldir] added the ability to declare dependencies on other modules in a module definition qmldir file Task-number: QTBUG-41489 Change-Id: Icd526bc7617bc3e4f725c7d008d0522a201cf645 Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@digia.com> Reviewed-by: Topi Reiniö <topi.reinio@digia.com>
* qmlimportscanner: parse "depends" lines in qmldir filesShawn Rutledge2014-10-011-2/+23
| | | | | | | | | | | | | These lines specify additional hidden dependencies. The first use case is in QtQuick.Dialogs: DefaultFileDialog.qml uses FolderListModel, but this file is not listed in the qmldir because the decision whether to use it is made at runtime. So QtQuick.Dialogs qmldir contains this: depends Qt.labs.folderlistmodel 1.0 Task-number: QTBUG-41489 Change-Id: Ide4bca2ce2e342b95e9a87cc418d26f331372d12 Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@digia.com> Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@digia.com>
* qmldir parser: add support for "depends component version" syntaxShawn Rutledge2014-10-014-0/+65
| | | | | | | | | | | | Dependency declarations are initially for the benefit of qmlimportscanner which does not (yet) use this parser. This patch adds support for dependencies into the qmldir parser for completeness, along with autotests. It is necessary to prevent errors at runtime when parsing a qmldir which contains the "depends" declaration. Task-number: QTBUG-41489 Change-Id: Ief2524a30140c42874f94f1735755b171e15dcf7 Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@digia.com>
* Partially revert d9c531781e6c95f80681b3c82700833e1de88794Gunnar Sletta2014-10-015-48/+22
| | | | | | | | | | | | This logic changed then timing for when the layer's m_dirtyTexture was set and unset, which had some side effects. Revert to the old and known-to-work behavior of using a connection. Change-Id: I4048e7ae70491afe36b2d766e6c506d9febc44ed Task-number: QTBUG-41451 Reviewed-by: Mitch Curtis <mitch.curtis@digia.com> Reviewed-by: Giulio Camuffo <giulio.camuffo@jollamobile.com> Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
* Make Canvas use texture atlas for smallish Image based canvases.Gunnar Sletta2014-09-303-17/+10
| | | | | | | | | | | This makes Canvas with Image batchable in the renderer which means that it is feasible to have 100s of small Canvases in a scene, for instance as static icons rendered with a bit of script. Change-Id: I3ad57360d632b7093fd6993afa88ed35c21d178a Reviewed-by: Mitch Curtis <mitch.curtis@digia.com> Reviewed-by: Laszlo Agocs <laszlo.agocs@digia.com>
* Document that QQmlApplicationEngine's root item must be a window.Mitch Curtis2014-09-301-1/+5
| | | | | Change-Id: I22466e82105c9b56894a53400394d1124191f93d Reviewed-by: Robin Burchell <robin.burchell@viroteck.net>
* Fix compiler warningLars Knoll2014-09-301-0/+1
| | | | | | | | | Add a matching operator delete to our operator new to shut up MSVC. Task-number: QTBUG-40652 Change-Id: I1396094d23c4d0cfc88a73fabbab05f1d4ec7b44 Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
* Update the Calqltr demo visuals and engine logicTopi Reinio2014-09-306-52/+181
| | | | | | | | | | | | | | | | - Add logic for displaying the calculation result in the best available precision, determined by the display width - Display 'ERROR' when the result cannot be displayed - Animate the number pad button colors to react to presses and visually disable them when pressing the button has no effect - Fix issues in calculator.js logic - Update documentation accordingly Task-number: QTBUG-41253 Change-Id: Ibed7b8218ea4cd074b8f9b90d9bb4e3ea6b25ba2 Reviewed-by: Johanna Äijälä <johanna.aijala@digia.com> Reviewed-by: Leena Miettinen <riitta-leena.miettinen@digia.com> Reviewed-by: Venugopal Shivashankar <venugopal.shivashankar@digia.com>
* Doc: Combine the extending QML tutorial chapters into a single exampleTopi Reinio2014-09-3049-119/+81
| | | | | | | | | | | | | Combine the six examples associated with each tutorial chapter into a single, top-level example project 'extending-qml', with subprojects for each of the tutorial chapters. Clean up the docs, add links, and a note about a warning that the user may see when running the code in the first chapter. Task-number: QTBUG-32947 Change-Id: Idba4e2153817ab29f1afaf1947d1f2e25964e7b3 Reviewed-by: Leena Miettinen <riitta-leena.miettinen@digia.com>
* Fix build when using -WerrorSérgio Martins2014-09-301-1/+1
| | | | | | | | | "'borderBottom' may be used uninitialized in this function [-Werror=maybe-uninitialized]" Observed when compiling for android. Change-Id: Ifcb26e28440f08528a192ea2fe88d6343e33710b Reviewed-by: BogDan Vatra <bogdan@kde.org>
* Add orientationUpdateMask to QQuickScreenAlex Blasche2014-09-304-1/+47
| | | | | | Task-number: QTBUG-38699 Change-Id: I173b7e53c27dba336351572859f7c9aeafe07ef9 Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@digia.com>
* Revert "Temporarily mark grab()/item.layer tests insignificant under ANGLE"Andrew Knight2014-09-302-36/+0
| | | | | | | | | This reverts commit 6b31418a1b5d9be47df5ed61747e8a5fb225acfa. These tests now pass with the latest ANGLE. Change-Id: If812d430e69f0d39a970e9119ebc1f2e5b4886dc Reviewed-by: Friedemann Kleint <Friedemann.Kleint@digia.com>
* Partially revert "Disable tests on failing ANGLE config"Andrew Knight2014-09-301-3/+0
| | | | | | | | | This partially reverts commit fa29df24bd2792f5eb64e4ff21a116b2c5f5384c. The sprite sequence test now passes in CI under MSVC2010. Change-Id: Ie8f7abdd2ff00db377b1ef3f221c5048c430c067 Reviewed-by: Friedemann Kleint <Friedemann.Kleint@digia.com>
* Fix example in scope documentationSimon Hausmann2014-09-301-2/+2
| | | | | | | | | | | | | The example tried to demonstrate the use of direct access to properties of the root component object, but unfortunately it also defined an id property that clashed with it. Therefore the provided example did not work as intended and produced a "stringified" object reference instead of the text of the "title" property. This patch changes the id to avoid a clash. Change-Id: Ib9abcf48482773a0dcdf5e2375d1445d87ccf4ef Reviewed-by: Michael Brasser <michael.brasser@live.com>
* Also search for visual children in TestCase::findChild().Mitch Curtis2014-09-292-3/+66
| | | | | | | | | It previously used QObject::findChild(), which won't work in all cases, because items like ListView don't seem to make their delegate items QObject children, while simple nested Items do. Change-Id: I1a8ed1fb55493212cb25abf595d016437812a80f Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
* Give Item::layer documentation some much needed love.Gunnar Sletta2014-09-2910-2/+460
| | | | | Change-Id: I31e038d961d3aa09a36db0c091c4e4910e395c2e Reviewed-by: Laszlo Agocs <laszlo.agocs@digia.com>
* qmlimportscanner: allow a qmlFile to come from stdinFawzi Mohamed2014-09-251-16/+26
| | | | | Change-Id: I22b0e45a8aa25d232791cdbeca15b5bc7400ae7d Reviewed-by: Thomas Hartmann <Thomas.Hartmann@digia.com>
* Doc: Replace VisualDataModel with DelegateModelNico Vertriest2014-09-252-21/+21
| | | | | | | Task-number: QTBUG-37725 Change-Id: Iad3b31470af8ea965d19b3d0901822b901407d40 Reviewed-by: Venugopal Shivashankar <venugopal.shivashankar@digia.com> Reviewed-by: Topi Reiniö <topi.reinio@digia.com>
* Updated calqlatr demoJohanna Aijala2014-09-254-15/+54
| | | | | | | | | | | | | | | | Fixes and finetuning of calqlatr demo: - fixed text overlapping, changed max length of a number from 14 to 9 - fixed app "freeze" after entering number of maximum length - implemented +/- operator functionality - fixed listview scrolling, after multiple operations listview was scrolling only when entering '=' leaving the active line hidden when the numbers and operator were typed - added support for entering numbers and certain operators from keyboard - removed commented code Task-number: QTBUG-38818 Change-Id: Ic0ecd2dff68a89007421e95a5bdc3ab7ca2e401d Reviewed-by: Topi Reiniö <topi.reinio@digia.com>
* Doc: Add docs for Clocks exampleLeena Miettinen2014-09-251-3/+89
| | | | | Change-Id: I626376ae2a169f7d892e86309754633e9ed6a6e9 Reviewed-by: Topi Reiniö <topi.reinio@digia.com>
* Reset 'invalidatePending' after the FBO has been recreated.Gunnar Sletta2014-09-251-0/+1
| | | | | | | | | If not, we will always request a new FBO during updatePaintNode, even when the fbo is not following the items size. Task-number: QTBUG-41565 Change-Id: I20b4b3a8e3630ff963a876320808869bba62fb8a Reviewed-by: Laszlo Agocs <laszlo.agocs@digia.com>
* QDSM: Nested statemachines are supportedSebastian Sauer2014-09-243-8/+72
| | | | | | | | | | | | | | * Remove wrongly printed info that nested statemachines are not supported. * Added autotest for nested statemachines. * Re-enable commented out testcase in the nestedInitalStates autotest. The reason why the test was disabled was fixed a while ago. Change-Id: I921483fa49d751d14c877f8f63335fa88cf2ce7b Reviewed-by: Brett Stottlemyer <bstottle@ford.com> Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
* move QQuickWindowAttached to QQuickWindowQmlImplShawn Rutledge2014-09-243-12/+7
| | | | | | | | | | It causes problems to do qmlRegisterType on QQuickWindow if the attached property also refers to QQuickWindow. Task-number: QTBUG-40816 Task-number: QTBUG-41047 Change-Id: I7a6f75af52f65e2be022b97128702982bec7cbe8 Reviewed-by: J-P Nurmi <jpnurmi@digia.com>
* Fix cleanup of non-threaded render loops.Gunnar Sletta2014-09-243-61/+42
| | | | | | | | | | | | | | | | | | | | | | They would unconditionally call cleanupNodesOnShutdown on hide(), but QQuickWindow::sceneGraphInvalidated would only be emitted if this was the last window being hidden, leading to an inconsistent state in the application. Since the non-threaded render loops do not support releasing resources (there is one OpenGL context and one QSGRenderContext shared between all windows) we delay cleanup until the window is destroyed. This change also make the render loops track the windows until they are destroyed, similar to what the threaded one does. The purpose of this is to, in the case of dangling windows, only trigger invalidation of the scene graph when the last QQuickWindow is destroyed through QSGRenderLoop::cleanup(). Task-number: QTBUG-41210 Change-Id: I7e12a4f726ebb3e7935c822b6046abb3590c583a Reviewed-by: Ulf Hermann <ulf.hermann@digia.com> Reviewed-by: Laszlo Agocs <laszlo.agocs@digia.com>
* Cleanup: Simplify CompiledData::Unit structure to always include the string ↵Simon Hausmann2014-09-244-14/+28
| | | | | | | table at the end Change-Id: Iae86b8f4dc0dc67c14974472f627e28d6795369f Reviewed-by: Lars Knoll <lars.knoll@digia.com>
* Allow multiple cached qml unit registration functionsSimon Hausmann2014-09-241-5/+7
| | | | | | | | Only few will be necessary, but this allows for greater flexibility at run-time. Change-Id: Ia03abeb6296a5dee97544209c578dc2974af7cbc Reviewed-by: Lars Knoll <lars.knoll@digia.com>
* Fix disappearing slider during size/orientation changeAlex Blasche2014-09-244-3/+80
| | | | | | | | | | | | | | Now the slider remains at a position that is equivalent to the old position based on the previous percentage. This change is most commonly triggered during orientation changes on mobile device. That is the reason why the app was converted to a proper Qt project. This way it was possible to test this behavior on Android. Task-number: QTBUG-18423 Change-Id: If05e6a1e42249f90a821c4882021d28cf212fc52 Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
* Doc: apply title case to all section1 titlesNico Vertriest2014-09-2415-27/+27
| | | | | | Task-number: QTBUG-41250 Change-Id: I303d989992c9685f73baae50c64accf71b43549f Reviewed-by: Topi Reiniö <topi.reinio@digia.com>
* Updated the example to accept input on AndroidVenu2014-09-231-1/+5
| | | | | | | | | | | | | | The Android inputMethod doesn't commit the text until a word is chosen from the suggestions list. This makes the URL for XMLHTTPRequest invalid. To avoid the invalid URL, we should either not use predictive text or explicitly commit the text. I choose to go with the earlier option. Task-number: QTBUT-41335 Change-Id: Id03c4dc8cfbd1b32cc2868fe8b78cd039994ff71 Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@digia.com> Reviewed-by: Topi Reiniö <topi.reinio@digia.com>
* Recreate the fbo on screen change in QQuickWidget when neededLaszlo Agocs2014-09-232-29/+34
| | | | | | | | | | | | Move the rendering code out into a separate function since it is now called from three places. Like in QOpenGLWidget, the FBO may need to be recreated with a different size in case the window is moved onto a screen with a different device pixel ratio. Change-Id: Iaaa42a06dab9e02710b0a7dafb0ea8c018b69ec2 Reviewed-by: Gunnar Sletta <gunnar@sletta.org>
* Add missing import to documentation code snippetSérgio Martins2014-09-231-0/+1
| | | | | Change-Id: I358b306fb286ffb00d2edd51bc3d97f1884fe34e Reviewed-by: Alan Alpert (Personal) <416365416c@gmail.com>