Ignore size hints when maximizing X11 windows
This is to help to fix maximized xwayland windows not covering the whole work area. Size hints are obeyed only when restoring the window. According to the net wm spec, the window manager should not obey size hints when maximizing a window and some other window managers already ignore them when maximizing windows. CCBUG: 459373
This commit is contained in:
parent
47317a9fc7
commit
2491fb1b2b
1 changed files with 15 additions and 92 deletions
|
@ -4440,30 +4440,6 @@ void X11Window::maximize(MaximizeMode mode)
|
|||
|
||||
MaximizeMode old_mode = max_mode;
|
||||
|
||||
// if the client insist on a fix aspect ratio, we check whether the maximizing will get us
|
||||
// out of screen bounds and take that as a "full maximization with aspect check" then
|
||||
const bool isX11Mode = kwinApp()->operationMode() == Application::OperationModeX11;
|
||||
|
||||
if (m_geometryHints.hasAspect() && // fixed aspect
|
||||
(mode == MaximizeVertical || mode == MaximizeHorizontal) && // ondimensional maximization
|
||||
rules()->checkStrictGeometry(isX11Mode)) { // obey aspect
|
||||
const QSize minAspect = m_geometryHints.minAspect();
|
||||
const QSize maxAspect = m_geometryHints.maxAspect();
|
||||
if (mode == MaximizeVertical || (old_mode & MaximizeVertical)) {
|
||||
const double fx = minAspect.width(); // use doubles, because the values can be MAX_INT
|
||||
const double fy = maxAspect.height(); // use doubles, because the values can be MAX_INT
|
||||
if (fx * clientArea.height() / fy > clientArea.width()) { // too big
|
||||
mode = old_mode & MaximizeHorizontal ? MaximizeRestore : MaximizeFull;
|
||||
}
|
||||
} else { // mode == MaximizeHorizontal
|
||||
const double fx = maxAspect.width();
|
||||
const double fy = minAspect.height();
|
||||
if (fy * clientArea.width() / fx > clientArea.height()) { // too big
|
||||
mode = old_mode & MaximizeVertical ? MaximizeRestore : MaximizeFull;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mode = rules()->checkMaximize(mode);
|
||||
if (max_mode == mode) {
|
||||
return;
|
||||
|
@ -4542,19 +4518,17 @@ void X11Window::maximize(MaximizeMode mode)
|
|||
|
||||
case MaximizeVertical: {
|
||||
if (old_mode & MaximizeHorizontal) { // actually restoring from MaximizeFull
|
||||
if (geometryRestore().width() == 0 || !clientArea.contains(geometryRestore().center())) {
|
||||
if (geometryRestore().width() == 0) {
|
||||
// needs placement
|
||||
resize(constrainFrameSize(QSize(width() * 2 / 3, clientArea.height()), SizeModeFixedH));
|
||||
const QSizeF constraintedSize = constrainFrameSize(QSizeF(width() * 2 / 3, clientArea.height()), SizeModeFixedH);
|
||||
resize(QSizeF(constraintedSize.width(), clientArea.height()));
|
||||
workspace()->placement()->placeSmart(this, clientArea);
|
||||
} else {
|
||||
moveResize(QRectF(QPointF(geometryRestore().x(), clientArea.top()),
|
||||
constrainFrameSize(QSize(geometryRestore().width(), clientArea.height()), SizeModeFixedH)));
|
||||
QSize(geometryRestore().width(), clientArea.height())));
|
||||
}
|
||||
} else {
|
||||
QRectF r(x(), clientArea.top(), width(), clientArea.height());
|
||||
r.setTopLeft(rules()->checkPosition(r.topLeft()));
|
||||
r.setSize(constrainFrameSize(r.size(), SizeModeFixedH));
|
||||
moveResize(r);
|
||||
moveResize(QRectF(x(), clientArea.top(), width(), clientArea.height()));
|
||||
}
|
||||
info->setState(NET::MaxVert, NET::Max);
|
||||
break;
|
||||
|
@ -4562,19 +4536,17 @@ void X11Window::maximize(MaximizeMode mode)
|
|||
|
||||
case MaximizeHorizontal: {
|
||||
if (old_mode & MaximizeVertical) { // actually restoring from MaximizeFull
|
||||
if (geometryRestore().height() == 0 || !clientArea.contains(geometryRestore().center())) {
|
||||
if (geometryRestore().height() == 0) {
|
||||
// needs placement
|
||||
resize(constrainFrameSize(QSize(clientArea.width(), height() * 2 / 3), SizeModeFixedW));
|
||||
const QSizeF constraintedSize = constrainFrameSize(QSizeF(clientArea.width(), height() * 2 / 3), SizeModeFixedW);
|
||||
resize(QSizeF(clientArea.width(), constraintedSize.height()));
|
||||
workspace()->placement()->placeSmart(this, clientArea);
|
||||
} else {
|
||||
moveResize(QRectF(QPoint(clientArea.left(), geometryRestore().y()),
|
||||
constrainFrameSize(QSize(clientArea.width(), geometryRestore().height()), SizeModeFixedW)));
|
||||
QSize(clientArea.width(), geometryRestore().height())));
|
||||
}
|
||||
} else {
|
||||
QRectF r(clientArea.left(), y(), clientArea.width(), height());
|
||||
r.setTopLeft(rules()->checkPosition(r.topLeft()));
|
||||
r.setSize(constrainFrameSize(r.size(), SizeModeFixedW));
|
||||
moveResize(r);
|
||||
moveResize(QRectF(clientArea.left(), y(), clientArea.width(), height()));
|
||||
}
|
||||
info->setState(NET::MaxHoriz, NET::Max);
|
||||
break;
|
||||
|
@ -4610,67 +4582,18 @@ void X11Window::maximize(MaximizeMode mode)
|
|||
}
|
||||
setGeometryRestore(restore); // relevant for mouse pos calculation, bug #298646
|
||||
}
|
||||
if (m_geometryHints.hasAspect()) {
|
||||
restore.setSize(constrainFrameSize(restore.size(), SizeModeAny));
|
||||
}
|
||||
|
||||
restore.setSize(constrainFrameSize(restore.size(), SizeModeAny));
|
||||
moveResize(restore);
|
||||
if (!clientArea.contains(geometryRestore().center())) { // Not restoring to the same screen
|
||||
workspace()->placement()->place(this, clientArea);
|
||||
}
|
||||
|
||||
info->setState(NET::States(), NET::Max);
|
||||
updateQuickTileMode(QuickTileFlag::None);
|
||||
break;
|
||||
}
|
||||
|
||||
case MaximizeFull: {
|
||||
QRectF r(clientArea);
|
||||
r.setTopLeft(rules()->checkPosition(r.topLeft()));
|
||||
r.setSize(constrainFrameSize(r.size(), SizeModeMax));
|
||||
if (r.size() != clientArea.size()) { // to avoid off-by-one errors...
|
||||
if (isElectricBorderMaximizing() && r.width() < clientArea.width()) {
|
||||
r.moveLeft(std::max(clientArea.left(), Cursors::self()->mouse()->pos().x() - r.width() / 2));
|
||||
r.moveRight(std::min(clientArea.right(), r.right()));
|
||||
} else {
|
||||
r.moveCenter(clientArea.center());
|
||||
const bool closeHeight = r.height() > 97 * clientArea.height() / 100;
|
||||
const bool closeWidth = r.width() > 97 * clientArea.width() / 100;
|
||||
const bool overHeight = r.height() > clientArea.height();
|
||||
const bool overWidth = r.width() > clientArea.width();
|
||||
if (closeWidth || closeHeight) {
|
||||
Qt::Edge titlePos = titlebarPosition();
|
||||
const QRectF screenArea = workspace()->clientArea(ScreenArea, this, clientArea.center());
|
||||
if (closeHeight) {
|
||||
bool tryBottom = titlePos == Qt::BottomEdge;
|
||||
if ((overHeight && titlePos == Qt::TopEdge) || screenArea.top() == clientArea.top()) {
|
||||
r.setTop(clientArea.top());
|
||||
} else {
|
||||
tryBottom = true;
|
||||
}
|
||||
if (tryBottom && (overHeight || screenArea.bottom() == clientArea.bottom())) {
|
||||
r.setBottom(clientArea.bottom());
|
||||
}
|
||||
}
|
||||
if (closeWidth) {
|
||||
bool tryLeft = titlePos == Qt::LeftEdge;
|
||||
if ((overWidth && titlePos == Qt::RightEdge) || screenArea.right() == clientArea.right()) {
|
||||
r.setRight(clientArea.right());
|
||||
} else {
|
||||
tryLeft = true;
|
||||
}
|
||||
if (tryLeft && (overWidth || screenArea.left() == clientArea.left())) {
|
||||
r.setLeft(clientArea.left());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
r.moveTopLeft(rules()->checkPosition(r.topLeft()));
|
||||
}
|
||||
// The above code tries to center align the window followed by setting top and bottom
|
||||
// it's possible that we're in between two pixels
|
||||
r = Xcb::nativeFloor(r);
|
||||
|
||||
moveResize(r);
|
||||
if (options->electricBorderMaximize() && r.top() == clientArea.top()) {
|
||||
moveResize(clientArea);
|
||||
if (options->electricBorderMaximize()) {
|
||||
updateQuickTileMode(QuickTileFlag::Maximize);
|
||||
} else {
|
||||
updateQuickTileMode(QuickTileFlag::None);
|
||||
|
|
Loading…
Reference in a new issue