From 484c33bf25a37952a91123fb728e4b983e70f531 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20L=C3=BCbking?= Date: Sun, 10 Apr 2016 22:40:15 +0200 Subject: [PATCH] prevent clients from positioning out of workspace Still enough stupid ones around which ask for 0,0 (despite there's a panel ...) or restore a position on a VGA screen which they stored while being on a 4k screen. Otoh, do not forcefully position the window just because the topleft position is outside any head, this can still be desired and isn't a problem. Actually, the corner could be covered by the close button and if *only* it is onscreen the window can hardly by used or seen. --- src/Window.cc | 41 +++++++++++++++++++++++++++++++++++------ 1 file changed, 35 insertions(+), 6 deletions(-) diff --git a/src/Window.cc b/src/Window.cc index 109b5222..f800e852 100644 --- a/src/Window.cc +++ b/src/Window.cc @@ -457,14 +457,43 @@ void FluxboxWindow::init() { setWindowType(m_client->getWindowType()); - bool is_visible = isWindowVisibleOnSomeHeadOrScreen(*this); - - if (fluxbox.isStartup()) + if (fluxbox.isStartup()) { m_placed = true; - else if (m_client->normal_hint_flags & (PPosition|USPosition)) { - m_placed = is_visible; + } else if (m_client->normal_hint_flags & (PPosition|USPosition)) { + m_placed = true; + // sanitize explicit position + int head = screen().getHead(fbWindow()); + if (head == 0 && screen().hasXinerama()) + head = screen().getCurrHead(); + int left = screen().maxLeft(head), top = screen().maxTop(head), + btm = screen().maxBottom(head), rght = screen().maxRight(head); + const int margin = hasTitlebar() ? 32 : 8; + // ensure the window intersects with the workspace x-axis + if (int(frame().x() + frame().width()) < left) { + left += margin - frame().width(); + } else if (frame().x() > rght) { + left = rght - margin; + } else { + left = frame().x(); + } + if (hasTitlebar()) { + // ensure the titlebar is inside the workspace + top = std::max(top, std::min(frame().y(), btm - margin)); + } else { + // ensure "something" is inside the workspace + if (int(frame().y() + frame().height()) < top) + top += margin - frame().height(); + else if (frame().y() > btm) + top = btm - margin; + else + top = frame().y(); + } + frame().move(left, top); } else { - if (!is_visible) { + if (!isWindowVisibleOnSomeHeadOrScreen(*this)) { + // this probably should never happen, but if a window + // unexplicitly has its topleft corner outside any screen, + // move it to the current screen and ensure it's just placed int cur = screen().getHead(fbWindow()); move(screen().getHeadX(cur), screen().getHeadY(cur)); m_placed = false; // allow placement strategy to fix position