[Development] Window{} API for QML

lars.knoll at nokia.com lars.knoll at nokia.com
Thu Nov 10 09:29:58 CET 2011


On 11/10/11 1:32 AM, "Alan Alpert" <alan.alpert at nokia.com> wrote:

>On Wed, 9 Nov 2011 06:43:34 Knoll Lars (Nokia-MP-Qt/Oslo) wrote:
>> I agree with most of the things in this thread, but not everything.
>>Here's
>> my thoughts:
>> 
>> We need a Window {} element to create surfaces on a physical screen.
>>This
>> Window object should IMO be more or less a direct representation of
>> QQuickView in QML.
>> 
>> So far we all seem to agree.  But I also do not see a need to limit the
>> Window {} API to the mobile use cases. I'd rather that we expose the
>>full
>> functionality in one Object, and rather document some of the differences
>> in behavior between mobile and desktop.
>
>I'm wary of trying to expose desktop APIs for desktop use cases,
>especially 
>before Desktop QML is fully realized. We might end up exposing the wrong
>then 
>and then we're at the same point as before plus we're maintaining and
>supporting use-impaired code. I'm also not fond of providing an element
>for 
>use in mobile contexts with functionality that basically says: "Don't use
>this". If it's not to be used on those platforms, why even have it
>available 
>for those platforms?

I think we have quite some stuff to test it. Jens desktop components are
IMO enough to test all the concepts required in terms of handling top
level windows for the desktop.

>
>As far as I'm aware there is a lot of features in this gap. Window
>decorations, modality, even geometry could be construed as desktop only.

Depends. And don't forget there are also devices such as tablets that are
something between desktop and mobile devices.

> 
>> Using the Window {} object anywhere in QML creates a new top level
>>window.
>> This implies that a Window{} as the root item of a QQuickView would
>>create
>> an empty QQuickView and a second top-level created through the WIndow
>> object. But at least this would mean there's no magic involved.
>> 
>
>Yep.
> 
>> Like that we can change the default way of using QML to be symmetric
>> between Desktop and Mobile. You instantiate a QQuickEngine, and then
>>load
>> a QML file that contains a WIndow {} as the outermost element. If we
>> remove the Window {} in QtComponents and use this instead, we can then
>> make this fully symmetrical on the QML side between desktop and mobile.
>> The only difference would be in the default behavior of Window (most
>> likely full screen on mobile, windowed on desktop).
>
>One of the changes talked about on the qt-components mailing list is that
>with 
>this approach you no longer have a Window{} as the outermost element in
>desktop components.

Why not? If you start a QQuickEngine instead of a View, then the Window{}
can still be the outermost element. In fact this would IMO give us
something more consistent. Of course you can still do a QQuickView
directly, but then you don't have a Window as the outermost element
anymore.
>
>I would rather have the C++ controlled windows exposed manually through
>C++ 
>and have the QML Window{}'s separate. This sounds easily exposed through
>ApplicationWindow{} anyways.

Not sure I understand what you mean here. If you use a QQuickWindow from
C++, you also control it from C++. If you use a QML Window{} you can
control it form QML.
>
>> Differentiation between mobile and desktop can then happen on the
>> ApplicationWindow level in QtComponents, where the ApplicationWindow for
>> the desktop would support menu- and toolbars, the mobile version would
>> support pages and whatever else is needed there.
>> 
>> In addition, it should be easy to associate a Window {} with a certain
>> physical screen. For this I'd propose, we somehow expose the list of
>> screens as objects in Qt.application, and give Window {} a screen
>>property
>> that can be bound to a screen.
>> 
>> So
>> 
>> Window {
>>     screen: Qt.application.primaryScreen // the default behavior
>> }
>> 
>> would create a Window on the primary screen.
>> 
>> The main question I'm unsure about is what to do with Windows on screens
>> that are going away (by unplugging the VGA cable going to the
>>projectorÅ ).
>
>I've been thinking about the screen issue, and my conclusion was that
>this 
>approach wouldn't work. Exposing the screens this way through
>Qt.application 
>wasn't deemed useful in the QScreen API thread, and a lot of the same
>problems 
>arise here. Aside from the primary screen, it will be very difficult to
>bind 
>this window to the right other screen, you can't just go off of list
>index 
>(except perhaps in the common case of external displays) so you need to
>query 
>the new screens on screenAdded/startup and imperatively assign windows.
>If 
>you're going to do it the imperative way anyways, you may as well do it
>in C++ 
>and just move Window{} objects out of the main QML file into another
>canvas 
>(that way they were created in the same engine and have useful bindings).

I tend to disagree. The reason is that you don't want to do many of these
things from C++. I agree that an imperative API is not ideal, but we're
having similar things in e.g. the PageStack.

>
>So here's my suggestion for what would work. Leave the general case for
>C++ as 
>explained above, and offer a convenience of the common case of an
>external 
>display. Example:
>
>ExternalDisplay{
>	Rectangle{
>		anchors.fill: parent
>	}
>}
>
>Arguably you could require a Window instead and automatically rescreen
>it, but 
>I prefer relaxing the restriction to any QQuickItem and it's just like
>the 
>root item in another view.
>
>As you can guess, the effect of the ExternalDisplay{} is that it will
>dynamically load and unload the child component and place it on any
>secondary 
>display when it's available. The root item for that display will be
>scaled 
>much like a QQuickView.

Sounds like an interesting idea. But I'm not sure we should or need to
limit ourselves to this.
>
>I've been trying to prototype it recently, but my efforts are currently
>stalled by the XCB plugin crashing when you try to do any GL on a
>secondary 
>screen :( . So I'm sorry, but I don't have the code for this yet.
> 
>> So my proposal would be something exposing most of the QWindow API:
>> 
>> Window {
>>     property Screen screen
>>     property Orientation orientation // { Portrait, Landscape, Å  }
>
>Isn't orientation a property of the screen? If we have a good screen API,
>we 
>don't need to duplicate this in the window.

There's two things that we need: A readonly property from the Screen
telling us what the current physical orientation of the screen is. In
addition, the app needs to tell the compositor what the orientation of the
content of this window is. The two don't need to agree (think about a game
that wants to enforce Landscape). Telling the compositor about the current
orientation is important for use cases such as notifications or VKB.

>
>>     property Rect geometry // or x, y, width, height
>>     property WindowFlags windowflags
>>     property Window parent
>
>This won't work if the root Window is not a Window{}. I don't think we
>can 
>just 'expose' QWindow as Window{}, as Window{} needs to create a new
>QQuickCanvas and reparent the subtree. Nor do I like making QQuickView a

If the root window is created in C++, you have to control it from C++.

My idea was that we'd change the recommended way of creating apps from
instantiating a QQuickView in C++ to instantiating a QQuickEngine in C++
and then using Window{} from QML.

Like that we'd get a much more symmetric ways of dealing with surfaces and
have complete control over them from QML.

> 
>WindowItem, for reasons explained earlier. I'd actually prefer they stick
>with 
>just the QQuickItem parent hierarchy and not add a third one, but that
>would 
>require a bit of magic in mapToGlobal functions or such to support the
>absolute positioning case (unless there's some aspect of the window
>parenting 
>hierarchy that I'm unaware of).
>
>>     property real opacity
>>     property string title
>>     ...
>> }
>> 
>> I'd go for a similar approach for Screen, basically exposing QScreen.
>> 
>> If the API of these classes aren't suitable for direct use in QML (after
>> adding properties with notifications of course), let's fix them. It's
>>new
>> API in Qt5 and we can still work on it and make it directly usable from
>> QML.
>
>I'm not convinced it has to be *directly* usable from QML. I liked the

I think this is something we need to aim for more. I don't see why making
the API suitable for QML would have to compromise the C++ side. It
probably would improve the C++ API as well.

> 
>attached property syntax for QScreen, and that would of course be
>impossible 
>to do directly with the QScreen class. The QScreen and QWindow C++ APIs
>need 
>to be directly usable from C++ first, which I assume they are, and then
>exposable to QML in a manner usable declaratively. But I'd rather have an
>extra layer translating them to QML than compromise their C++ performance
>(assuming that layer is thin and efficient of course).

I don't see why this should compromise the C++ performance in any way.
>
>> If we get this in, I believe we have a good part of the foundations in
>> place to give us really good multi screen support in QML as well as
>>having
>> what's needed to build desktop components directly on QtQuick2.
>
>Those are of course good goals. Does anyone know of anything else needed
>to 
>build desktop components directly on QtQuick2?

Yes, there are a few other building blocks required. One I'm working on
(when I find time) is shortcut handling. I'm almost done moving the
infrastructure into QtGui. Once that's there it should be straightforward
to create a Shortcut{} QML element.

The last piece is of course native theming. Initially we can do the hack
and use QStyle to get the information, but longer term we need to think
about how to do this better, as QStyle is heavily dependent on the
QtWidgets module.

Cheers,
Lars





More information about the Development mailing list