Due to an influx of spam, we have had to impose restrictions on new accounts. Please see this wiki page for instructions on how to get full permissions. Sorry for the inconvenience.
Admin message
The migration is almost done, at least the rest should happen in the background. There are still a few technical difference between the old cluster and the new ones, and they are summarized in this issue. Please pay attention to the TL:DR at the end of the comment.
The spec [1] says that wl_output::transform's rotation is counter-clockwise.
However, configuring an output with a 90 degree rotation results in a clockwise rotation. The output rotation reported by weston-info is 90.
90 and 270 degree rotations are swapped. Their flipped variants are swapped too.
This isn't a big issue inside weston because weston apps (like weston-terminal) will behave correctly: they'll rotate their surfaces of 90 degrees clockwise and advertize via wl_surface::set_buffer_transform a 90 degree rotation.
This is more of an issue with other compositors. If another compositor wants to follow the spec, weston apps won't work correctly in this compositor.
From the spec: "This describes the transform that a compositor will apply to a surface to compensate for the rotation or mirroring of an output device."
I always get confused whether you rotate the monitor or the surface. So if surface is rotated 90 degrees counter-clockwise, it means the monitor is rotated 90 degrees clockwise. I tried with Weston and you seem to be right: wl_output::transform in weston describes the monitor rotation, not surface rotation.
Because weston.ini is documented as 90 being clockwise rotation of the image, not the monitor, it matches the current Weston behaviour. We'd need to invert the rotation read from weston.ini for sending to clients, and also invert the image rotations we do in Weston and weston clients... right?
We'd need to invert the rotation read from weston.ini for sending to clients, and also invert the image rotations we do in Weston and weston clients... right?
Yes, I think so. Except we also need to do this for all existing clients and compositors.
At this point I'd say a spec fix and clarification is probably better. What do you think?
I think Mir does the same as Weston and wlroots here - rotating the display image 90⁰ clockwise (so rotating the laptop 90⁰ anti-clockwise makes the screen the right way up) results in Mir advertising WL_OUTPUT_TRANSFORM_270. (I also find it difficult to really grasp what the spec is saying, so that's why I'm not sure if this is the same behaviour as Weston )
A simple way to test is running weston-transformed and pressing the arrow left/right keys. If the image doesn't change, your compositor behaves like Weston.
I finally managed to test on KWin myself. I installed Plasma Wayland from Ubuntu 19.10 (KDE Plasma 5.16.5, Qt 5.12.4).
To me it seems that KWin does not handle buffer transform at all. When playing with unmodified weston-transformed, all orientations except "normal" show up wrong.
If a compositor gets only the direction of the transform wrong, then only transforms with 90 and 270 would show up wrong and the rest would show up right.
@shadeslayer@romangg Did I test an outdated version of KWin, or is this so also in master?
For my new proposed, hopefully more clear wording, see wayland!57 (closed). Note, that the specification there has the opposite definition than the current wording.
Sorry in advance for the lengthy post. I'm worried I've misunderstood something and just want to explain my thinking in case someone else with an interest in Qt wants to double check.
TL;DR: Qt client and compositor implementations seem in line with the protocol, but the compositor API documentation is wrong.
Feel free to ignore the rest of this post if you're not interested in the details.
voidQWaylandScreen::updateOutputProperties(){if(mTransform>=0){boolisPortrait=mGeometry.height()>mGeometry.width();switch(mTransform){caseWL_OUTPUT_TRANSFORM_NORMAL:m_orientation=isPortrait?Qt::PortraitOrientation:Qt::LandscapeOrientation;break;caseWL_OUTPUT_TRANSFORM_90:m_orientation=isPortrait?Qt::InvertedLandscapeOrientation:Qt::PortraitOrientation;break;caseWL_OUTPUT_TRANSFORM_180:m_orientation=isPortrait?Qt::InvertedPortraitOrientation:Qt::InvertedLandscapeOrientation;break;caseWL_OUTPUT_TRANSFORM_270:m_orientation=isPortrait?Qt::LandscapeOrientation:Qt::InvertedPortraitOrientation;break;// Ignore these ones, at least for nowcaseWL_OUTPUT_TRANSFORM_FLIPPED:caseWL_OUTPUT_TRANSFORM_FLIPPED_90:caseWL_OUTPUT_TRANSFORM_FLIPPED_180:caseWL_OUTPUT_TRANSFORM_FLIPPED_270:break;}QWindowSystemInterface::handleScreenOrientationChange(screen(),m_orientation);mTransform=-1;}QWindowSystemInterface::handleScreenRefreshRateChange(screen(),refreshRate());if(!zxdg_output_v1::isInitialized())QWindowSystemInterface::handleScreenGeometryChange(screen(),geometry(),geometry());}
How I understand it:
Let's say we have a regular landscape screen (width > height at the lower levels), but it has been rotated 90 degrees clockwise. The compositor should then report WL_OUTPUT_TRANSFORM_90 as it's going to rotate the client buffers 90 degrees counter-clockwise to compensate for the physical rotation.
It looks like we're then going to set QScreen::orientation to Qt::PortraitOrientation, which is documented as: Portrait orientation, display height is greater than display width, rotated 90 degree clockwise relative to landscape.
So, assuming the Qt application is orientation aware (has called QScreen::setOrientationUpdateMask and has rendered itself rotated and called QWindow::reportContentOrientationChange with Qt::PortraitOrientation, then QWaylandWindow::handleContentOrientationChange will be called with Qt::PortraitOrientation.
voidQWaylandWindow::handleContentOrientationChange(Qt::ScreenOrientationorientation){if(mDisplay->compositorVersion()<2)return;wl_output_transformtransform;boolisPortrait=window()->screen()&&window()->screen()->primaryOrientation()==Qt::PortraitOrientation;switch(orientation){caseQt::PrimaryOrientation:transform=WL_OUTPUT_TRANSFORM_NORMAL;break;caseQt::LandscapeOrientation:transform=isPortrait?WL_OUTPUT_TRANSFORM_270:WL_OUTPUT_TRANSFORM_NORMAL;break;caseQt::PortraitOrientation:transform=isPortrait?WL_OUTPUT_TRANSFORM_NORMAL:WL_OUTPUT_TRANSFORM_90;break;caseQt::InvertedLandscapeOrientation:transform=isPortrait?WL_OUTPUT_TRANSFORM_90:WL_OUTPUT_TRANSFORM_180;break;caseQt::InvertedPortraitOrientation:transform=isPortrait?WL_OUTPUT_TRANSFORM_180:WL_OUTPUT_TRANSFORM_270;break;default:Q_UNREACHABLE();}mSurface->set_buffer_transform(transform);// set_buffer_transform is double buffered, we need to commit.mSurface->commit();}
When handleContentOrientationChange is setting isPortrait, it's reading from QScreen::primaryOrientation, not QScreen::orientation. primaryOrientation should as far as I understand be set to landskape as width > height. So isPortrait will be false, which means QWindow::contentOrientation is going to request set_buffer_transform(WL_OUTPUT_TRANSFORM_90), which I guess seems to be in line with the spec.
* \qmlproperty enum QtWaylandCompositor::WaylandSurface::contentOrientation * * This property holds the orientation of the WaylandSurface's contents. * * \sa {WaylandOutput::transform}{WaylandOutput.transform}
Which I guess is incorrect, as it's not really the orientation of the surface, but what kind of orientation the client has already compensated for. So I would say the implementation—despite being incomplete—is correct, but the documentation is not.
I know for a fact that Qt + Weston is quite widely used in a few environments, particularly including automotive. I don't know how they compensate for the mismatch in rotations between the two. Often the layouts are just hardcoded anyway, as they're aimed for very fixed displays.
At this point, given the relative userbases, I would argue that we should fix the spec to reflect the most popular reality, rather than fixing reality to reflect the spec.
Fixing this will probably screw up a lot of setups, regardless of which option we choose. And I don't particularly like the idea of also breaking the spec.
Non Qt wayland clients are pretty rare in Sailfish, I can think of two internally which can be patched at the same time as QtWayland if need be.
And I think the output and buffer orientations are being misused at the moment. The output orientation is being used to forward the reading from an orientation sensor and the buffer orientation returns the rotation of the client UI which the homescreen UI rotates to match. So there are probably compatibility issues with non-Sailfish clients already.
@adenexter thanks for letting us know! Yeah, that's not what the protocol intended, quite creative abuse I'd say. :-)
I also understand where that comes from, when you need to dynamically adapt to physical orientation changes and the client needs to re-render before the visual orientation can change. If we did that on Wayland by the book, I think you'd add some more state to xdg_toplevel and use ack_configure or window state to trigger the visual orientation change. The wl_output and wl_buffer transforms are mostly for optimizing the pixel path once the visual orientation has been set.
In mutter, we implement it in the same way as weston, i.e. not according to spec, but we never advertise wl_output's as having any transforms. Historically, because we didn't implement buffer transforms, and we still don't for cursor surface buffers. Thus, in practice, changing mutter to implement buffer transforms according to spec would likely not cause any issues in practice for GNOME, as buffer transforms are likely mostly, if not only except for test cases, in response to wl_output transforms.
I know for a fact that Qt + Weston is quite widely used in a few environments, particularly including automotive. I don't know how they compensate for the mismatch in rotations between the two. Often the layouts are just hardcoded anyway, as they're aimed for very fixed displays.
If Qt + Weston use cases hardcode everything, then I suppose it should be fairly easy to fix the fallout if I fix Weston to honor the spec as is, right?
OTOH Qt + Qt Wayland compositor is very much unknown to me, but Johan suggests it could break badly.
KWin has no released implementation of tranforms, and GNOME/mutter seems fine fixing theirs.
I would interpret the situation like this:
keep spec as is
change spec
either way
Mir
KWin
EFL
GNOME
Qt
weston
GTK+
wlroots
"Keep spec as is" also has one "default" vote in my opinion, because it is the word of the spec and it is not even ambiguous, even if it is a little hard to read.
I propose that "Keep the spec as is" wins.
Yays? Nays? Does anyone want to move to a different column?