[wayland] Handle sizes in ShellClient::transientPlacement
Summary: placeIn did not handle the case for a popup not having had the size already set and only being available via m_xdgShellPopup->initialSize(). This is needed if we want to call placeIn at the correct time, before the window is mapped. There was also a logic bug when sliding popups. We called the confusingly named setX thinking it would be move the popup keeping the width the same. In practice it moves the left edge keeping the right position the same. This wasn't an issue as the size was discarded. Handling the resize constraint is not yet done, but it should now be even more trivial. Reviewers: #kwin, zzag Reviewed By: #kwin, zzag Subscribers: zzag, kwin Tags: #kwin Differential Revision: https://phabricator.kde.org/D18956
This commit is contained in:
parent
40477aff2d
commit
7014a33992
3 changed files with 20 additions and 14 deletions
|
@ -500,8 +500,9 @@ void Placement::placeTransient(AbstractClient *c)
|
|||
{
|
||||
const auto parent = c->transientFor();
|
||||
const QRect screen = Workspace::self()->clientArea(parent->isFullScreen() ? FullScreenArea : PlacementArea, parent);
|
||||
const QPoint popupPos = c->transientPlacement(screen).topLeft();
|
||||
c->move(popupPos);
|
||||
const QRect popupGeometry = c->transientPlacement(screen);
|
||||
c->setGeometry(popupGeometry);
|
||||
|
||||
|
||||
// Potentially a client could set no constraint adjustments
|
||||
// and we'll be offscreen.
|
||||
|
|
|
@ -1453,6 +1453,7 @@ QRect ShellClient::transientPlacement(const QRect &bounds) const
|
|||
Qt::Edges gravity;
|
||||
QPoint offset;
|
||||
PositionerConstraints constraintAdjustments;
|
||||
QSize size = geometry().size();
|
||||
|
||||
const QPoint parentClientPos = transientFor()->pos() + transientFor()->clientPos();
|
||||
QRect popupPosition;
|
||||
|
@ -1486,12 +1487,16 @@ QRect ShellClient::transientPlacement(const QRect &bounds) const
|
|||
gravity = m_xdgShellPopup->gravity();
|
||||
offset = m_xdgShellPopup->anchorOffset();
|
||||
constraintAdjustments = m_xdgShellPopup->constraintAdjustments();
|
||||
if (!size.isValid()) {
|
||||
size = m_xdgShellPopup->initialSize();
|
||||
}
|
||||
} else {
|
||||
Q_UNREACHABLE();
|
||||
}
|
||||
|
||||
|
||||
//initial position
|
||||
popupPosition = QRect(popupOffset(anchorRect, anchorEdge, gravity) + offset + parentClientPos, geometry().size());
|
||||
popupPosition = QRect(popupOffset(anchorRect, anchorEdge, gravity, size) + offset + parentClientPos, size);
|
||||
|
||||
//if that fits, we don't need to do anything
|
||||
if (inBounds(popupPosition)) {
|
||||
|
@ -1510,20 +1515,21 @@ QRect ShellClient::transientPlacement(const QRect &bounds) const
|
|||
if (flippedGravity & (Qt::LeftEdge | Qt::RightEdge)) {
|
||||
flippedGravity ^= (Qt::LeftEdge | Qt::RightEdge);
|
||||
}
|
||||
auto flippedPopupPosition = QRect(popupOffset(anchorRect, flippedAnchorEdge, flippedGravity) + offset + parentClientPos, geometry().size());
|
||||
auto flippedPopupPosition = QRect(popupOffset(anchorRect, flippedAnchorEdge, flippedGravity, size) + offset + parentClientPos, size);
|
||||
|
||||
//if it still doesn't fit we should continue with the unflipped version
|
||||
if (inBounds(flippedPopupPosition, Qt::LeftEdge | Qt::RightEdge)) {
|
||||
popupPosition.setX(flippedPopupPosition.x());
|
||||
popupPosition.moveLeft(flippedPopupPosition.x());
|
||||
}
|
||||
}
|
||||
}
|
||||
if (constraintAdjustments & PositionerConstraint::SlideX) {
|
||||
if (!inBounds(popupPosition, Qt::LeftEdge)) {
|
||||
popupPosition.setX(bounds.x());
|
||||
popupPosition.moveLeft(bounds.x());
|
||||
}
|
||||
if (!inBounds(popupPosition, Qt::RightEdge)) {
|
||||
popupPosition.setX(bounds.x() + bounds.width() - geometry().width());
|
||||
// moveRight suffers from the classic QRect off by one issue
|
||||
popupPosition.moveLeft(bounds.x() + bounds.width() - size.width());
|
||||
}
|
||||
}
|
||||
if (constraintAdjustments & PositionerConstraint::ResizeX) {
|
||||
|
@ -1542,20 +1548,20 @@ QRect ShellClient::transientPlacement(const QRect &bounds) const
|
|||
if (flippedGravity & (Qt::TopEdge | Qt::BottomEdge)) {
|
||||
flippedGravity ^= (Qt::TopEdge | Qt::BottomEdge);
|
||||
}
|
||||
auto flippedPopupPosition = QRect(popupOffset(anchorRect, flippedAnchorEdge, flippedGravity) + offset + parentClientPos, geometry().size());
|
||||
auto flippedPopupPosition = QRect(popupOffset(anchorRect, flippedAnchorEdge, flippedGravity, size) + offset + parentClientPos, size);
|
||||
|
||||
//if it still doesn't fit we should continue with the unflipped version
|
||||
if (inBounds(flippedPopupPosition, Qt::TopEdge | Qt::BottomEdge)) {
|
||||
popupPosition.setY(flippedPopupPosition.y());
|
||||
popupPosition.moveTop(flippedPopupPosition.y());
|
||||
}
|
||||
}
|
||||
}
|
||||
if (constraintAdjustments & PositionerConstraint::SlideY) {
|
||||
if (!inBounds(popupPosition, Qt::TopEdge)) {
|
||||
popupPosition.setY(bounds.y());
|
||||
popupPosition.moveTop(bounds.y());
|
||||
}
|
||||
if (!inBounds(popupPosition, Qt::BottomEdge)) {
|
||||
popupPosition.setY(bounds.y() + bounds.height() - geometry().height());
|
||||
popupPosition.moveTop(bounds.y() + bounds.height() - size.height());
|
||||
}
|
||||
}
|
||||
if (constraintAdjustments & PositionerConstraint::ResizeY) {
|
||||
|
@ -1565,9 +1571,8 @@ QRect ShellClient::transientPlacement(const QRect &bounds) const
|
|||
return popupPosition;
|
||||
}
|
||||
|
||||
QPoint ShellClient::popupOffset(const QRect &anchorRect, const Qt::Edges anchorEdge, const Qt::Edges gravity) const
|
||||
QPoint ShellClient::popupOffset(const QRect &anchorRect, const Qt::Edges anchorEdge, const Qt::Edges gravity, const QSize popupSize) const
|
||||
{
|
||||
const QSize popupSize = geometry().size();
|
||||
QPoint anchorPoint;
|
||||
switch (anchorEdge & (Qt::LeftEdge | Qt::RightEdge)) {
|
||||
case Qt::LeftEdge:
|
||||
|
|
|
@ -210,7 +210,7 @@ private:
|
|||
void updateMaximizeMode(MaximizeMode maximizeMode);
|
||||
// called on surface commit and processes all m_pendingConfigureRequests up to m_lastAckedConfigureReqest
|
||||
void updatePendingGeometry();
|
||||
QPoint popupOffset(const QRect &anchorRect, const Qt::Edges anchorEdge, const Qt::Edges gravity) const;
|
||||
QPoint popupOffset(const QRect &anchorRect, const Qt::Edges anchorEdge, const Qt::Edges gravity, const QSize popupSize) const;
|
||||
static void deleteClient(ShellClient *c);
|
||||
|
||||
KWayland::Server::ShellSurfaceInterface *m_shellSurface;
|
||||
|
|
Loading…
Reference in a new issue