[Development] Window{} API for QML

Alan Alpert alan.alpert at nokia.com
Thu Nov 10 01:32:18 CET 2011


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?

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.
 
> 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.

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.

> 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).

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.

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.

>     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 
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 
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).

> 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?

-- 
Alan Alpert
Senior Engineer
Nokia, Qt Development Frameworks



More information about the Development mailing list