[Development] Architecture of Android/Java bindings for QML and QtQuick

2024-05-31 Thread Ulf Hermann via Development

Hi,

As noted before, we need to have a discussion on the new Android/Java 
bindings and how they fit in with the QML language and various Qt 
modules. See for example 
https://codereview.qt-project.org/c/qt/qtdeclarative/+/563564 and 
various follow-up changes.


I suggest we call the Android/Java bindings Tech Preview for now.

My main gripe is that the way it's written now, the language bindings, 
the mapping of various model types, and the QtQuick support are all 
added in one big package in src/quick. This limits what you can do with 
e.g. the QtQmlComponent wrapper class. Ideally a QtQmlComponent should 
be a generic building block for creating any QML component, independent 
of any particular UI toolkit. There should also be a generic wrapper for 
a QML engine that could instantiate QML components. This way we'd be 
able to use the same building blocks for other Qt modules that expose 
QML types, without depending on QtQuick.


For example: QtScxml has a QML integration that can be used without 
QtQuick in C++. If you tie the Java-QML language bindings in with 
QtQuick, you suddenly need to use QtQuick when employing the same 
QtScxml/QML integration from Java. Such a thing will not sit well with 
the maintainer of QtScxml.


I suggest to split the Java bindings into separate packages for each Qt 
module, so that you can use them independently. The QtQml bindings 
should provide common QML-related building blocks, such as a wrapper for 
a QML engine and a wrapper for a QML component, that can be re-used in 
other modules.


best regards,
Ulf
--
Development mailing list
Development@qt-project.org
https://lists.qt-project.org/listinfo/development


Re: [Development] Feature freeze exception: QtAbstractItemModel, QtModelIndex and QtAbstactListModel

2024-05-31 Thread Ulf Hermann via Development

Hi,

First, I don't think you need a feature freeze exception to write tests, 
examples and documentation. Those are not new features, after all.


Second, while I certainly welcome this initiative to produce 
Android/Java bindings for QtQuick, we need to have some discussion about 
the overall architecture before we can consider this stable API. But 
let's start a separate mail thread about that.


best regards,
Ulf
--
Development mailing list
Development@qt-project.org
https://lists.qt-project.org/listinfo/development


Re: [Development] qmlcachegen and QQC2 styles

2024-05-13 Thread Ulf Hermann via Development

Hi,

Generally, if I read that correctly, a user would rarely need both of 
your styles. They either have a Desktop type device or a Mobile type 
device and running the other style makes little sense.


Therefore, in your case, I would propose to compile two variants of all 
your libraries: one that assumes desktop and one that assumes mobile. 
Either of those would only deal with one style. Most users would only 
install one of those variants.


On the practical side, you'd have the style to be used as a CMake 
property somewhere and you'd have a wrapper module called 
QtQuick.Controls.KDE, the only purpose of which is to import this style. 
Then, wherever you import QtQuick.Controls currently, you'd import 
QtQuick.Controls.KDE instead. From that point on, you can compile the 
two variants of all dependent libraries and applications without further 
changes.


If some user actually wants both variants installed, you can use some 
mechanism like /etc/alternatives or similar to switch between them.


Now, we could also find a fix for this on the Qt side. It would involve 
additional config files, some weaker form of whole-class FINAL and extra 
warnings from qmllint etc if you shadow properties you shouldn't shadow. 
This would be a whole lot of infrastructure, and I currently don't quite 
see who would build it. We should probably talk at Qt Contributors' 
Summit about this (and all the other proposals we've recently seen).


best regards,
Ulf
--
Development mailing list
Development@qt-project.org
https://lists.qt-project.org/listinfo/development


Re: [Development] Nominating Lucie Gerard for approver rights

2024-04-24 Thread Ulf Hermann via Development

I'd like to nominate Lucie Gerard as an approver for the Qt project.


+1, how was she not an approver, yet?!
--
Development mailing list
Development@qt-project.org
https://lists.qt-project.org/listinfo/development


Re: [Development] On Removing Public Undocumented/\internal APIs

2024-03-04 Thread Ulf Hermann via Development

Hi,

there is another category of such API: API for use by generated code 
only, such as qqmlprivate.h. This is intentionally undocumented, 
intentionally called by generated user code, and the run time guards 
around the generated code make sure it's not called if the run time Qt 
version does not match the compile time one.


best regards,
Ulf
--
Development mailing list
Development@qt-project.org
https://lists.qt-project.org/listinfo/development


[Development] Proposing QUIP 22: Define Rules for Q_PROPERTYs in Qt

2024-02-14 Thread Ulf Hermann via Development

Hi,

we cannot retroactively make properties FINAL as that can be source 
incompatible in QML. However, FINAL properties result in a significant 
performance boost for QML. qmlcachegen, if it can prove that a property 
you use in your code is actually the property it expects, does not have 
to wrap it in QVariant and type-check it at run time. You may want to 
read 
https://www.qt.io/blog/qt-6.6-and-6.7-make-qml-faster-than-ever-a-new-benchmark-and-analysis 
and compare the numbers for "Shadowable" and "Static" in the graph. 
qmlsc has an extra (dangerous) argument "static" that makes it treat all 
properties as FINAL. If you make your properties FINAL to begin with, 
you get the same benefit without qmlsc and the extra argument.


So here is my proposal for QUIP 22: 
https://codereview.qt-project.org/c/meta/quips/+/539986


I've thrown in rules for BINDABLE and REVISION there, too. Those also 
come up quite frequently.


best regards,
Ulf
--
Development mailing list
Development@qt-project.org
https://lists.qt-project.org/listinfo/development


Re: [Development] Documentation and Q_GADGET / Q_PROPERTY

2024-01-15 Thread Ulf Hermann via Development

The one thing where you need NOTIFY or BINDABLE is if you want to expose a 
class as a type to QML
AND you want to make its instances usable in bindings; I believe that's where 
the warning originates
from. However,  that's not your use-case, so it shouldn't matter.


Value types do not need signals or bindables on their properties, even 
when exposed to QML. Since value types can only be held in properties of 
object types (possibly via multiple nested value types), there is always 
an object property the signal of which is used to notify about changes 
in the value type properties.


regards,
Ulf
--
Development mailing list
Development@qt-project.org
https://lists.qt-project.org/listinfo/development


Re: [Development] Multiple QML engines with different import paths, file selectors, etc

2024-01-09 Thread Ulf Hermann via Development
Hi, have you considered how you can keep compatibility, by making this 
change either opt-in or opt-out? Since it seems the refactoring is 
already done, it feels like you are making a bet that only has a 
negative outcome for those porting/trying to keep up.  Good for 
maintenance, bad for users?


OK, I'm convinced. My experiments have unearthed lots of "interesting" 
behavior, but the basic example of having two engines with different 
import paths both load some document works. That is, the resulting QML 
types are indeed different. So I've dropped 
https://codereview.qt-project.org/c/qt/qtdeclarative/+/527526 - the 
change that makes compilation units visible across engines. The 
refactoring for splitting the compilation units in a way that eliminates 
engine pointers from the global type registry is still a good idea, but 
it can be done without any functional changes.


The minimal fix for QTBUG-120189 is to double check the engine-specific 
type loader for any property type added to the property caches. This 
isn't pretty but it does the trick. See 
https://codereview.qt-project.org/c/qt/qtdeclarative/+/529215


In the long run, we have to untangle this somehow. You can't have 
different types for the same document in different engines and _also_ 
store all of this in a global type registry that assumes you have a 
unique type for each URL. Currently this assumption is enforced in some 
places but deliberately avoided in others.


When we get qmltc and qmlcachegen into a shape where the code generated 
by qmltc can directly call the functions and expressions compiled by 
qmlcachegen we won't need much of an engine anymore if you exclusively 
run pre-compiled code. When running the QML code through the interpreter 
or JIT we might then duplicate the type registry for each engine and 
isolate the type registries against each other. Those could then be 
safely used with custom import paths, URL interceptors etc. That's still 
quite a way to go, though.


best,
Ulf
--
Development mailing list
Development@qt-project.org
https://lists.qt-project.org/listinfo/development


Re: [Development] Multiple QML engines with different import paths, file selectors, etc

2024-01-09 Thread Ulf Hermann via Development

So, to clarify this some more ... If:

1. you use _multiple_ QML engines in the same process at the same time, 
2. you have _different_ import paths, plugin paths, URL interceptors or 
network access managers for those engines,
3. you rely on those engines to produce _different results_ for the 
_same QML documents_ as a consequence,

4. this actually _works_,

please let me know more about your use case!

Using multiple engines A, B, ... sequentially where you only start 
accessing the type registry from engine B after engine A has been 
destructed does not count since engine A will clean up after itself.


From my point of view, looking at the source code, such a scenario is 
rather unlikely since the global type registry should get in your way. 
However, if it exists, I will consider it in my refactoring.


best,
Ulf
--
Development mailing list
Development@qt-project.org
https://lists.qt-project.org/listinfo/development


Re: [Development] Multiple QML engines with different import paths, file selectors, etc

2024-01-08 Thread Ulf Hermann via Development
Hi, have you considered how you can keep compatibility, by making this 
change either opt-in or opt-out? Since it seems the refactoring is 
already done, it feels like you are making a bet that only has a 
negative outcome for those porting/trying to keep up.  Good for 
maintenance, bad for users?


I'm specifically asking here for any use cases that aren't already 
broken. If you have something like that, please let me know. I will 
consider it. I can't really make the whole thing opt-in or opt-out 
without leaving QTBUG-120189 open.


best,
Ulf
--
Development mailing list
Development@qt-project.org
https://lists.qt-project.org/listinfo/development


[Development] Multiple QML engines with different import paths, file selectors, etc

2024-01-08 Thread Ulf Hermann via Development

Hi,

I'm currently refactoring our QML compilation units to avoid storing 
engine-specific data in the global type registry since that is dangerous 
and bug-prone. See e.g. QTBUG-120189.


This effectively means that you will be able to re-use compilation units 
between different QML engines. On the surface that is great because your 
QML engines won't re-compile the same code over and over. However, there 
are certain attributes to QML engines that can make them produce 
different QML components from the same code:


1. Import paths. You might store different modules with the same URI in 
different import paths and make them available selectively to only 
select engines in your process.


2. File selectors (or more generally URL interceptors). You can re-write 
URLs any way you like and you can assign different interceptors to 
different engines.


3. Network access managers. You can implement the same URL scheme in 
different ways between different engines.


Different import paths can be useful in reality for versioning of QML 
modules, but you should certainly not use different versions of the same 
module within the same process. Using different file selectors or 
different network access managers between QML engines running in the 
same process sounds rather obscure to me.


Now when I'm done with the refactoring, if you do such things, one of 
your engines may dig up components compiled by one of the other engines 
with the other engine's settings. That's bad. However:


1. I believe the use cases for this are rather few and far between. 
Please correct me if I'm wrong.


2. Since we already have a type registry that currently stores fully 
engine-specific compilation units, I'm sure there are plenty of bugs in 
this area that already do turn up the wrong compilation units if used in 
such a way.


3. Different components will also produce different property caches and 
ultimately different metaobjects. Those are fundamentally global already 
and should give you plenty of problems if you're doing this.


In conclusion, I will go ahead with the changes. In addition, I will 
probably add static versions of those settings (import paths, URL 
interceptors, network access managers) and deprecate the engine-specific 
settings, so that you can't accidentally mess this up either.


best,
Ulf
--
Development mailing list
Development@qt-project.org
https://lists.qt-project.org/listinfo/development


Re: [Development] Nominating Semih Yavuz as an approver for the Qt project

2023-12-07 Thread Ulf Hermann via Development

+1

Disclosure: Semih is working in my team and we share the same office.


Same for me

best regards,
Ulf
--
Development mailing list
Development@qt-project.org
https://lists.qt-project.org/listinfo/development


Re: [Development] std::optional for Q_PROPERTY

2023-11-27 Thread Ulf Hermann via Development

How about conversion:

 QVariant(std::optional>).value(); // return U{} if T cannot be 
converted; otherwise U(T);

 QVariant().value>(); // nullopt, not a std::optional 
holding a T{}
 QVariant(42).value>(); // std::optional holding 42
 QVariant(QSize()).value>(); // probably nullopt?


QML checks the metatype before doing anything interesting with an 
unknown piece of QVariant. If it knows it's an optional (after some 
teaching it), it would also know how to retrieve the T value. Nullopt 
should indeed be mapped to void in QML and undefined in JS.


QVariant is not the best way to encode an optional. Since QML would 
have to know about it's meaning anyway, we should use the otpional 
itself as the value passed to/from getter and setter. We wouldn't need 
any special hackery in QVariant and/or moc for that.


If we make QML understand "optional" as a native concept the same way it 
understands "list", we generally add type registration overhead. I was 
already somewhat unwilling to do that for lists but I didn't come up 
with anything better back then. Each QML type now has a list "companion 
type" with a separate entry in the type registry. This is mostly because 
QMetaType doesn't tell us anything about list types. We need to store 
the information about the type being a list and what elements it can 
hold (and the default list type for a given element type) separately. 
The same thing will eventually happen for map and at latest if we add 
variant it's going to disintegrate. So, what we actually 
need is a better QML type registry and richer information from QMetaType.


It looks like we're going to discuss this at QtCS.

best regards,
Ulf
--
Development mailing list
Development@qt-project.org
https://lists.qt-project.org/listinfo/development


Re: [Development] Nominating QtGRPC & Qt Protobuf maintainers

2023-11-08 Thread Ulf Hermann via Development

I'd like to nominate Tatiana Borisova as maintainer for Qt Protobuf
and Alexey Edelev as maintainer for Qt GRPC. In fact, both have been
working on this code base even before they officially became part of
Qt. I am glad they agreed to continue this work going forward in the
context of Qt Development.


+1 from me

br,
Ulf
--
Development mailing list
Development@qt-project.org
https://lists.qt-project.org/listinfo/development


Re: [Development] Using qml.exe with a custom QML_ELEMENT plugin

2023-10-26 Thread Ulf Hermann via Development

I can confirm a simple:

     for (const QString  : parser.values(importOption)){
     QByteArray path = qgetenv("PATH");
     QByteArray newPath = importPath.toLocal8Bit() + ";";
     newPath += path;
     qputenv("PATH", newPath);
     qDebug() << "Modified PATH:" << qgetenv("PATH");
     e.addImportPath(importPath);
     }


I don't quite understand why this works. Can you show the directory 
layout in the respective import path? Where do the files end up?


In any case, it should be specific to windows, so please add an "#ifdef 
Q_OS_WIN". The best place to discuss this is actually the code review 
system. You don't necessarily have to open a feature ticket.


cheers,
Ulf
--
Development mailing list
Development@qt-project.org
https://lists.qt-project.org/listinfo/development


Re: [Development] Using qml.exe with a custom QML_ELEMENT plugin

2023-10-25 Thread Ulf Hermann via Development
Adding a command line option to add dll search paths via 
_wpuntenv_s(L"PATH", ...) or SetDLLDirectory(L"...") into qml.exe would 
also work, right?


I didn't know this exists. You'd have to add a lot of directories, 
though, since it doesn't want to see the QML import path but the paths 
to the individual modules I guess.


If you have a solution in mind, feel free to push a change to 
https://codereview.qt-project.org and add me as reviewer. It would be 
nice to make this work.

--
Development mailing list
Development@qt-project.org
https://lists.qt-project.org/listinfo/development


Re: [Development] Using qml.exe with a custom QML_ELEMENT plugin

2023-10-25 Thread Ulf Hermann via Development
According to dependency scanner it depends on Qt6Qml.dll, Qt6Core.dll 
and World.dll. All of these should be either be available from Qt or 
from the additional import path I provided. Even when copying the dlls 
into the directory, I get the same error.


This is not about the import path but about the windows dynamic linker 
being unable to load any library that's not in PATH or next to the 
application. The application, in this case is the "qml" tool in Qt. 
That's unfortunate, but this is just how it is on windows. It's not 
specific to QML modules Any library that's not next to your application 
has this problem. We have deployment tooling to deal with this.


best regards,
Ulf
--
Development mailing list
Development@qt-project.org
https://lists.qt-project.org/listinfo/development


Re: [Development] Using qml.exe with a custom QML_ELEMENT plugin

2023-10-25 Thread Ulf Hermann via Development
PS C:\Qt\6.7.0\msvc2019_64\bin> /.\qml.exe -I 
"C:\Code\Cpp\build-qml-plugin-minimal-Desktop_Qt_6_7_0_MSVC2019_64bit-Release" -f "C:\Code\Cpp\qml-plugin-minimal\Main.qml"

QQmlApplicationEngine failed to load component
file:///C:/Code/Cpp/qml-plugin-minimal/Main.qml:5:1: Die Bibliothek 
C:\Code\Cpp\build-qml-plugin-minimal-Desktop_Qt_6_7_0_MSVC2019_64bit-Release\Hello\World\Worldplugin.dll kann nicht geladen werden: Das angegebene Modul wurde nicht gefunden.

qml: Did not load any objects, exiting./


On windows, you have to jump through some hoops to make it find the 
backing library. There is PATH. You can install the backing library in 
some place that's already on your PATH or you can adapt PATH. If you 
have a custom executable you can also install the backing library next 
to it.

--
Development mailing list
Development@qt-project.org
https://lists.qt-project.org/listinfo/development


Re: [Development] Proposal: (re)move qt5.git/_clang-format

2023-09-13 Thread Ulf Hermann via Development

There _is_ consensus. It's in the wiki. And in older modules not
infected by the _clang-format file. Discussions arise because
of .clang-format, not despite it. Afaict, there never was a discussion
about how faithful the _clang-format represents the Qt style before it
was added. If there was _any_ attempt at the above-mentioned litmus
test, the template<> issue and others would have been detected immediately.


Unfortunately the consensus is weak on the most jarring problem, and 
that happens to be one that the automatic formatters I know are utter 
rubbish at:


Where do you break the line and how much white space do you indent in 
various situations? For example:


* long lists of arguments list to a function (call or declaration)
* nested template parameters, possibly with defaults
* template arguments
* lists of partially specialized template parameters
* initializer lists (possibly nested)
* ternary operators with outsized "hands"
* constructor-initializers
* lambdas, potentially nested
* nested boolean or arithmetic expressions with or without parentheses
* and then combine all of those

I find myself constantly re-indenting things based on some unwritten 
rules I make up myself. I would be fine with an automatic indentation 
that produces somewhat readable code, but what I get is frequently an 
indentation to column 205 or similar for no obvious reason.


Yes, it often helps to use additional temporaries so that your lines are 
not as large to begin with. However, that also increases the cognitive 
load when reading it as you then have to carefully determine if the 
introduction of the temporary changes semantics. For example, is the 
temporary moved or copied? Does the extracted template construction 
allow things the inline one was not meant to allow? etc.


All the other stuff you may format for is trivial in comparison because 
it only involves adding or removing few characters here or there. With 
some practice it takes up rather little time, even when done manually. 
The indentation, however, requires shifting around large bodies of white 
space, which is quite annoying in the editors I know.


best regards,
Ulf
--
Development mailing list
Development@qt-project.org
https://lists.qt-project.org/listinfo/development


Re: [Development] QtFluentMQ

2023-08-28 Thread Ulf Hermann via Development

+1, as indicated before
--
Development mailing list
Development@qt-project.org
https://lists.qt-project.org/listinfo/development


Re: [Development] CI failing due to ASan tst_selftest

2023-08-27 Thread Ulf Hermann via Development

==19383==ERROR: LeakSanitizer: detected memory leaks
  Direct leak of 48 byte(s) in 2 object(s) allocated from:
#0 0x7f26aec7ae48 in __interceptor_malloc (/usr/lib64/libasan.so.
5+0x109e48)
#1 0x7f26a8bcbc50  (/usr/lib64/libfontconfig.so.1+0xbc50)
#2 0x3d4c4c415f434bff  ()


I've seen this one before. I suspect certain versions of fontconfig have 
an internal memory leak. For me, it fixed itself after an upgrade of 
some packages. Can we install debug symbols for fontconfig on the 
respective platforms? Then we could see a proper stack trace.


best regards,
Ulf
--
Development mailing list
Development@qt-project.org
https://lists.qt-project.org/listinfo/development


Re: [Development] QtFluentMQ

2023-08-26 Thread Ulf Hermann via Development

Hi,

The usual way to request a repository, playground or not, is a mail like 
this:


https://lists.qt-project.org/pipermail/development/2022-August/042900.html

If the request is not totally outlandish it's usually granted, possibly 
after some bike shedding over the name and location.


AFAIR we haven't bike shedded over the commercial value of a new 
repository, the architecture of the code it shall hold, or its licensing 
before. I don't think we need to.


You should fill in at least the basic information, though: name and 
description, responsible person, and desired location.


At least sometimes, we have used the lazy consensus mechanism for 
repository requests in the past. This seems a good idea to me. I will +1 
this one if the (still missing) basics are reasonable.


We can still discuss the way to integrate with the rest of Qt once we 
can see some code.


best regards,
Ulf Hermann
--
Development mailing list
Development@qt-project.org
https://lists.qt-project.org/listinfo/development


Re: [Development] Nominating Tatiana Borisova as approver

2023-05-23 Thread Ulf Hermann via Development

+1

She has helped me more than once with obscure INTEGRITY-related problems.

Ulf
--
Development mailing list
Development@qt-project.org
https://lists.qt-project.org/listinfo/development


Re: [Development] Nominating Edward Welbourne as QLocale / date/time maintainer

2023-05-04 Thread Ulf Hermann via Development

+1

He's doing a great job.
--
Development mailing list
Development@qt-project.org
https://lists.qt-project.org/listinfo/development


Re: [Development] Is it a known bug in Qt5: https://bugreports.qt.io/browse/QTBUG-111754 ?

2023-03-06 Thread Ulf Hermann via Development
     The bug is not reproduce in Qt 6.4.2, but I can't found a exists 
issue in bugreports.qt.io. Maybe my Qt 5 is not latest version? It's Qt 
5.15.8, Is this bug fixed in the private Qt code?


https://bugreports.qt.io/browse/QTBUG-97427 is what you're looking for. 
I've linked it in QTBUG-111754. It's fixed in Qt 6.2.1. I'm not going to 
pick the fix back to 5.15.


The fix is https://codereview.qt-project.org/c/qt/qtdeclarative/+/376174

best,
Ulf

--
Development mailing list
Development@qt-project.org
https://lists.qt-project.org/listinfo/development


Re: [Development] Support for *Notes and UpstreamFiles fields in qt_attributions.json files

2023-02-15 Thread Ulf Hermann via Development

QML supports comments, but not multi-line string literals. You can concatenate
them, though.


Sure it does. You can use ECMAScript template strings:

property string longthing: `a multi
line string`

(In fact you can also just sprinkle line breaks into your regular 
strings. But don't.)

--
Development mailing list
Development@qt-project.org
https://lists.qt-project.org/listinfo/development


Re: [Development] Support for *Notes and UpstreamFiles fields in qt_attributions.json files

2023-02-15 Thread Ulf Hermann via Development

Or QML, in fact:


// Attribution.qml in QtAttribution module:
QtObject {
property string name
property list files
property list upstreamFiles
// 
}


// Actual attribution.qml in source tree:
import QtAttribution
Attribution {
// allows comments as much as you like
name: "Foobar"
files: ["some/file.h", "some/file.cpp"]
license: License.GPL // can be a QML enum in a License.qml
// ...
}


That would be all nicely human-readable and easily verified with 
qmllint. I get the argument for sticking with JSON now, though.


best,
Ulf
--
Development mailing list
Development@qt-project.org
https://lists.qt-project.org/listinfo/development


Re: [Development] Support for *Notes and UpstreamFiles fields in qt_attributions.json files

2023-02-14 Thread Ulf Hermann via Development
YAML is really quite terrible. If we're going to switch, let's choose 
something else.


Basically, YAML is extremely complex, ambiguous, and incompatible 
between different versions. See for example 
https://ruudvanasseldonk.com/2023/01/11/the-yaml-document-from-hell for 
an in-depth explanation.


Toml seems to be popular these days.

best regards,
Ulf
--
Development mailing list
Development@qt-project.org
https://lists.qt-project.org/listinfo/development


Re: [Development] How to fix TableView's API break?

2022-12-18 Thread Ulf Hermann via Development
So, how to fix the above? One could easily fix the API break, but one is 
left with broken APIs all over the place. There's no straightforward 
deprecation mechanism for QML either, and we've dropped versioned includes.


We haven't actually dropped versioned imports. An unversioned import 
just always imports the latest version. Versioned imports are somewhat 
broken in subtle ways (as they have always been). Therefore we recommend 
unversioned imports, but if there is a specific reason to use a 
versioned import, you still can.


There is in fact a deprecation mechanism via the @Deprecated QML 
annotation, but that is not public (yet), and it only works for 
QML-defined types, not for C++-defined ones. It shouldn't be too hard to 
add an analogous DEPRECATED property attribute and a Q_DEPRECATED method 
attribute to moc. Or we might re-use the C++ attributes and macros. Not 
in 6.4, though.


In the past we have just documented properties and methods as 
\deprecated in qdoc and left it at that. For example, FileDialog has 
some deprecated members.


best regards,
Ulf
___
Development mailing list
Development@qt-project.org
https://lists.qt-project.org/listinfo/development


Re: [Development] How qAsConst and qExchange lead to qNN

2022-11-16 Thread Ulf Hermann via Development

The above isn't thread-safe, it isn't even re-entrant, in the same way
that iteration using iterators isn't. This is a known issue whenever you
hand out references, and it's nothing that violates our
const-is-thread-safe promise, otherwise


... which is why we prefer to hand out (implicitly shared) copies rather 
than references.




  static const QMap map = ~~~;
  // T1
  map["x"].size();


Our container classes do hand out references, because containers have 
to. But in other places we avoid it.


best regards,
Ulf
___
Development mailing list
Development@qt-project.org
https://lists.qt-project.org/listinfo/development


Re: [Development] How qAsConst and qExchange lead to qNN

2022-11-16 Thread Ulf Hermann via Development

That's a deep copy. A deep copy of a string is obviously more expensive
than the overhead of calling the QString ctor and dtor.


That remains to be proven. A rule of thumb for atomics is that they're
two orders of magnitude slower than a normal int. They also still act as
optimizer firewalls. With that rule of thumb, copying 50 char16_t's is
faster than one ref-count update. What really is the deciding point is
whether or not there's a memory allocation involved. I mentioned that
for many use-cases, therefore, a non-CoW SBO container is preferable over a CoW
non-SBO one.


As stated elsewhere, the real problem about the deep copy is the 
allocation involved in it, not necessarily the copying of the elements.



I can't say what case is more common. What I can say is that the risk of
creating deep copies sounds worse to me than the risk of calling the
QString ctor and dtor too often.

This is what I mean with "fuzzy". We don't really have the data to
support a move to QAnyStringView for all of our API.


I can say with firm belief that, _atm_, passing QString is more common.
But this is a self-fulfilling fact. The tst_qsettings experiment shows
what can happen if you port an API that doesn't naturally receive
pre-made QStrings.


Are we in a position to change how people use our APIs? I can say with 
firm belief that most existing applications using Qt will not be 
rewritten from the ground up to avoid passing QString and QList to Qt 
APIs. So they will pay the cost of deep copies if we force 
QAnyStringView and QSpan on them by changing our API. There are lots of 
existing Qt applications. Your CO2 calculation doesn't look that great then.


New APIs that are not used in the "wrong" way all over the world, yet, 
are a different story. If we can provide a clean QAnyStringView or QSpan 
override without ambiguities, it's also  a different story. (But adding 
complexity to the API is still a thing).


Maybe we can approach this in a module-by-module way. QtWidgets is 
probably pretty "bad" regarding QList and QString arguments, and no one 
will change their old widgets applications to suit our newfangled 
containers.


QtQml and QtQuick, on the other hand, hardly have any C++ API, and most 
QML and QtQuick applications are not that old. We might get away with 
changing API there.


QtCore and QtGui is where the most difficult decisions are to be taken, 
I guess.


best regards,
Ulf
___
Development mailing list
Development@qt-project.org
https://lists.qt-project.org/listinfo/development


Re: [Development] How qAsConst and qExchange lead to qNN

2022-11-14 Thread Ulf Hermann via Development

So, if the method immediately converts whatever it gets to QList or
QString, then there is no point in passing it a span or view.


My point is that there _is_. Citing my blog post:

callConsumeQStringHelloWorld():

> [...]

That's the worst case scenario of passing an 8bit string literal to a 
function that takes a QString. We have QStringLiteral to avoid the 8bit 
to 16bit conversion, but I know there are more problems with that.


Now lets look at the case of passing a pre-existing QString (i.e. one we 
don't have to create in place) to a function taking QAnyStringView and 
storing the result as QString.


// somewhere:
QString a;
void setter(QAnyStringView view) { a = view.toString(); }

// elsewhere:
QString foo;
[ ... modify foo ... ]
setter(QAnyStringView(foo));

That's a deep copy. A deep copy of a string is obviously more expensive 
than the overhead of calling the QString ctor and dtor. Which case is 
more common? And by what factor?


I can't say what case is more common. What I can say is that the risk of 
creating deep copies sounds worse to me than the risk of calling the 
QString ctor and dtor too often.


This is what I mean with "fuzzy". We don't really have the data to 
support a move to QAnyStringView for all of our API.


best regards,
Ulf
___
Development mailing list
Development@qt-project.org
https://lists.qt-project.org/listinfo/development


Re: [Development] How qAsConst and qExchange lead to qNN

2022-11-14 Thread Ulf Hermann via Development

Hi Marc,


On 11.11.22 09:35, Ulf Hermann via Development wrote:

There is an undeniable benefit of _offering_ QSpan, QStringView, and
generator APIs in a few relevant cases:

1. Users want to pass a "foreign" container to a Qt function that
doesn't only store it as QList or QString. It might merely iterate it or
store it as something else.


The assumption that there's a problem only for "foreign containers" is
incorrect: Take the native Qt container QString as an example. See
assembly in my QAnyStringView blog post:
https://www.qt.io/blog/qstringview-diaries-qanystringview You have this
problem as soon as you pass constant data, which is a common enough
use-case to warrant optimizing for.


My point is the "doesn't only store it as QList or QString" and 
"foreign" is in quotes quite on purpose. Maybe that wasn't clear enough, 
though.


So, if the method immediately converts whatever it gets to QList or 
QString, then there is no point in passing it a span or view. Otherwise, 
since we don't know what people are going to do with the method (pass 
foreign containers, subsets, etc), a span or view may be adequate.


br,
Ulf
___
Development mailing list
Development@qt-project.org
https://lists.qt-project.org/listinfo/development


Re: [Development] How qAsConst and qExchange lead to qNN

2022-11-11 Thread Ulf Hermann via Development
There is an undeniable benefit of _offering_ QSpan, QStringView, and 
generator APIs in a few relevant cases:


1. Users want to pass a "foreign" container to a Qt function that 
doesn't only store it as QList or QString. It might merely iterate it or 
store it as something else.


2. Assume a container that isn't internally stored as QList or QString, 
but is returned from a Qt function. Users want to use that thing as 
something else than QString or QList. For example they might merely 
iterate it or store its contents in a "foreign" container.


In those cases, using QList or QString as transfer mechanism induces an 
unnecessary deep copy.


All other cases look much fuzzier to me. QSpan or QStringView (or a 
generator) may be beneficial or detrimental there, depending on exact 
usage pattern. The cost we're avoiding is mostly the reference count, a 
far cry from a deep copy. On the flip side we're introducing complex 
life time problems that will lead to hard to find memory management 
defects. I suggest we look at this from the perspective of a _user_ of 
Qt. I'm pretty sure you can all imagine which problem a user would 
prefer here.


So, I suggest we add those "view" APIs to the cases where they provide a 
clear benefit. For methods that return a span/view/generator, we should 
always offer a safe alternative that returns an owning container. The 
naming convention should be:


1. Use overloads for methods that take views or spans. In new API we can 
omit the methods that take owning containers. If the overload set grows 
out of hand, don't add the view/span alternative until we can remove 
something. By Thiago's argument, that means not to convert existing 
methods to QStringView for now.


2. Use the postfix "View", "Span" or "Generator" for methods that return 
views, spans or generators rather than owning containers. This way it's 
harder for users to mess up the life time.


best regards,
Ulf
___
Development mailing list
Development@qt-project.org
https://lists.qt-project.org/listinfo/development


Re: [Development] How qAsConst and qExchange lead to qNN

2022-11-09 Thread Ulf Hermann via Development

Hi,

let me mention that I've been pondering all that hairy stuff just 
recently when trying to come up with a solution for how to map QList*> and QQmlListProperty to each other without exposing people to 
dangling references and without copying and allocating all the time.


One thing we could do is add a special escape hatch to QSpan (or 
QQmlListProperty) that makes it easy to retrieve the underlying QList in 
the cases where it's just a thin wrapper around a complete QList. That 
thing could then be used to implicitly construct a (shared) QList from a 
QSpan.


With this, you'd get the old behavior if you just pass QList around. 
Your QLists are just wrapped and unwrapped in QSpans when passing Qt's 
API boundary. However, you could also pass other things that can be 
expressed as QSpan, and new Qt APIs could return QSpans that are not 
backed by QLists.


I realize that this proposal has very little to do with std::span. It 
also doesn't solve all of my problems with QQmlListProperty, but it 
might be part of a solution.


best regards,
Ulf

___
Development mailing list
Development@qt-project.org
https://lists.qt-project.org/listinfo/development


Re: [Development] How qAsConst and qExchange lead to qNN

2022-11-08 Thread Ulf Hermann via Development

I don't want to take the Qt containers away from Qt users. I want to get
rid of their use in our APIs, so that both the Qt implementation as well
as our users are free to choose the best container for their needs
instead of having to pick from one of the public Qt containers.


I would like to know how that is supposed to work in practice. We have a 
lot of public API dealing with Qt containers all over. What are you 
going to do to, for example, to


void addActions(const QList );

in qwidget.h? What should it look like when we're done and our users are 
free to choose the best container for their needs?


Mind that I'm specially interested in this because I'm currently facing 
a similar problem, making different container types available in QML. 
QML has its own poor man's "range" type in the form of QQmlListProperty 
and it's terrible.



  >> Q_FOREACH
  > [I can make 100% correct predictions about changes I intent to push,
  > too. What's the point?]

I have no desire to touch the implementation of Q_FOREACH, ever. I did,
unwillingly, when its users suffered unnecessary pessimisations in the
past, but the port to C++20 ranged-for-with-init is not of that kind.


Waiting for someone to push a patch with code you've already outlined 
and then approving it is pretty much the same as changing it yourself. 
You just don't need any approval for that ...


best regards,
Ulf
___
Development mailing list
Development@qt-project.org
https://lists.qt-project.org/listinfo/development


Re: [Development] Using '#pragma once' instead of include guards?

2022-11-04 Thread Ulf Hermann via Development

Once we had QString and QByteArray (and the admittedly ill-conceived
QStringRef). Now we have QStringView, QAnyStringView, QByteArrayView,
... and when asking what the prefered getter/setter-signature for
"Qt-style" interfaces is the answer I get is "We'd guess $X, but the
only guy that knows for sure is on holiday". And that's for "developers
using Qt", not "developers _of_ Qt". Is that something you'd
call "complicated"?


While I can sympathize with the idea of #pragma once, this is not a fair 
comparison. The current set of classes, while complicated, also does a 
lot more than what we previously had. If you want the only the old 
functionality you can just restrict yourself to QString, QByteArray, and 
QStringView. That's not actually more complicated.


But if you want classes that deal with UTF-8 and with views on different 
kinds of string data, you obviously need some more types.

___
Development mailing list
Development@qt-project.org
https://lists.qt-project.org/listinfo/development


Re: [Development] C++20 comparisons @ Qt (was: Re: C++20 @ Qt)

2022-11-04 Thread Ulf Hermann via Development

Hi,

One thing I haven't understood about the ordering problem is why we 
cannot just define our "invalid" values to always be < any valid one and 
equal to other invalid ones. This way we get at least weak ordering for 
all our types and we're done.


There may be types where existing operator< work differently (*cough* 
QTypeRevision), but that just means we need to emulate that same 
behavior with the new operators.


Indeed the NaN behavior has always been a pain to deal with every time 
I've encountered it. If we have a chance to avoid it, we should.


What is the downside of such an approach?

best regards,
Ulf
___
Development mailing list
Development@qt-project.org
https://lists.qt-project.org/listinfo/development


Re: [Development] Nominating Sami Shalayel as approver

2022-11-04 Thread Ulf Hermann via Development

+1

Unsurprisingly, I'm part of the same team as Sami
___
Development mailing list
Development@qt-project.org
https://lists.qt-project.org/listinfo/development


Re: [Development] Remaining tools in CMAKE_INSTALL_BINDIR

2022-10-10 Thread Ulf Hermann via Development

My question was for the developer's own plugins. Are these tools meant for
the developer to test their QML importing their plugins? It might be
surprising that it cannot find the plugins they've just installed to
QML_PLUGIN_PATH, or worse, finds an older version of them.


Indeed if you actually have both Qt5 and Qt6 available, a single qml or 
qmlscene executable cannot cover them both. So, let's make them versioned.


best regards,
Ulf
___
Development mailing list
Development@qt-project.org
https://lists.qt-project.org/listinfo/development


Re: [Development] Remaining tools in CMAKE_INSTALL_BINDIR

2022-10-07 Thread Ulf Hermann via Development

I would consider qml, qmlscene, qmlpreview, qmlprofiler, and qmltime to
be equivalent to their Qt 5 versions, and indeed user-facing.


And would replacing the Qt 5 versions with Qt 6 be an imperceptible change to
the user? What happens if their own QML content has plugins? I assume Qt
itself ships equivalent plugins to everything that hadn't been deprecated
before 6.0.


In a parallel install the Qt5 and Qt6 QML import paths should be 
separate. If you ship your own QML modules you can in principle build 
them against both Qt5 and Qt6, separately, and install them in the 
respective import paths. But I don't know if anyone actually does that.


We made an effort to keep Qt's own QML modules source compatible between 
Qt5 and Qt6, including versions. However, there are modules that 
blatantly break compatibility. QtMultimedia and QtLocation come to mind. 
No idea if those were deprecated before they were re-created for Qt6.



qmlplugindump is the same as in Qt5. It should be a build tool, but it
is not, due to ... shortcomings. People generally invoke it manually.
Also, it's deprecated in Qt6.


Can we disable its build & installation by default?


I guess that would make some people rather unhappy. I've seen some cold, 
dead hands clutching qmlplugindump.


Also, qmlplugindump actually loads plugins. So, although it's almost the 
same source code you cannot use the Qt5 qmlplugindump to read Qt6 
plugins, or vice versa.

___
Development mailing list
Development@qt-project.org
https://lists.qt-project.org/listinfo/development


Re: [Development] Remaining tools in CMAKE_INSTALL_BINDIR

2022-10-07 Thread Ulf Hermann via Development
I would consider qml, qmlscene, qmlpreview, qmlprofiler, and qmltime to 
be equivalent to their Qt 5 versions, and indeed user-facing.


Well, qml and qmlscene are only equivalent to Qt5 insofar as we consider 
the QML language and our QML modules in Qt6 to be equivalent to the ones 
in Qt5. There are some behavior changes and incompatibilities, of course.


best regards,
Ulf
___
Development mailing list
Development@qt-project.org
https://lists.qt-project.org/listinfo/development


Re: [Development] Remaining tools in CMAKE_INSTALL_BINDIR

2022-10-07 Thread Ulf Hermann via Development

Hi,

I would consider qml, qmlscene, qmlpreview, qmlprofiler, and qmltime to 
be equivalent to their Qt 5 versions, and indeed user-facing.


qmltc is not user-facing. It's a compiler and should live in the same 
place as qmlcachegen.


qmljs is a general-purpose JavaScript interpreter. So, it's kind of 
user-facing and equivalent to the Qt5 version. We only build it for 
developer builds, though (AFAIK).


qmlplugindump is the same as in Qt5. It should be a build tool, but it 
is not, due to ... shortcomings. People generally invoke it manually. 
Also, it's deprecated in Qt6.


qmldom is a debugging helper for the QmlDom library. As such it is user 
facing, bit it should only be built for developer builds.


best regards,
Ulf
___
Development mailing list
Development@qt-project.org
https://lists.qt-project.org/listinfo/development