Limit window position to prevent hiding its title bar when using single-window UI (fix #3839)

This commit is contained in:
Martín Capello 2023-07-05 18:01:25 -03:00 committed by David Capello
parent 7358626859
commit 1143e3bb4f
2 changed files with 53 additions and 25 deletions

View File

@ -518,17 +518,15 @@ bool Window::onProcessMessage(Message* msg)
// Reposition/resize // Reposition/resize
if (m_hitTest == HitTestCaption) { if (m_hitTest == HitTestCaption) {
int x = clickedWindowPos->x + (mousePos.x - clickedMousePos.x); gfx::Point pos = clickedWindowPos->origin() + mousePos - clickedMousePos;
int y = clickedWindowPos->y + (mousePos.y - clickedMousePos.y); gfx::Rect rect(pos, bounds().size());
moveWindow(gfx::Rect(x, y, // Limit window position to avoid hiding the title bar
bounds().w, limitPosition(rect);
bounds().h), true);
moveWindow(rect, true);
} }
else { else {
int x, y, w, h; gfx::Size size = clickedWindowPos->size();
w = clickedWindowPos->w;
h = clickedWindowPos->h;
bool hitLeft = (m_hitTest == HitTestBorderNW || bool hitLeft = (m_hitTest == HitTestBorderNW ||
m_hitTest == HitTestBorderW || m_hitTest == HitTestBorderW ||
@ -544,34 +542,38 @@ bool Window::onProcessMessage(Message* msg)
m_hitTest == HitTestBorderSE); m_hitTest == HitTestBorderSE);
if (hitLeft) { if (hitLeft) {
w += clickedMousePos.x - mousePos.x; size.w += clickedMousePos.x - mousePos.x;
} }
else if (hitRight) { else if (hitRight) {
w += mousePos.x - clickedMousePos.x; size.w += mousePos.x - clickedMousePos.x;
} }
if (hitTop) { if (hitTop) {
h += (clickedMousePos.y - mousePos.y); size.h += (clickedMousePos.y - mousePos.y);
} }
else if (hitBottom) { else if (hitBottom) {
h += (mousePos.y - clickedMousePos.y); size.h += (mousePos.y - clickedMousePos.y);
} }
limitSize(&w, &h); limitSize(size);
if ((bounds().w != w) || if (bounds().size() != size) {
(bounds().h != h)) { gfx::Point pos;
if (hitLeft) if (hitLeft)
x = clickedWindowPos->x - (w - clickedWindowPos->w); pos.x = clickedWindowPos->x - (size.w - clickedWindowPos->w);
else else
x = bounds().x; pos.x = bounds().x;
if (hitTop) if (hitTop)
y = clickedWindowPos->y - (h - clickedWindowPos->h); pos.y = clickedWindowPos->y - (size.h - clickedWindowPos->h);
else else
y = bounds().y; pos.y = bounds().y;
moveWindow(gfx::Rect(x, y, w, h), false); gfx::Rect rect(pos, size);
// Limit window rectangle to avoid hiding its borders when resizing
limitPosition(rect);
moveWindow(rect, false);
invalidate(); invalidate();
} }
} }
@ -755,10 +757,35 @@ void Window::windowSetPosition(const gfx::Rect& rect)
m_isResizing = false; m_isResizing = false;
} }
void Window::limitSize(int* w, int* h) void Window::limitSize(gfx::Size& size)
{ {
*w = std::max(*w, border().width()); size.w = std::max(size.w, border().width());
*h = std::max(*h, border().height()); size.h = std::max(size.h, border().height());
}
void Window::limitPosition(gfx::Rect& rect)
{
if (rect.y < 0) {
rect.y = 0;
rect.h = bounds().h;
}
auto titlebarH = childrenBounds().y - bounds().y;
auto limitB = parent()->bounds().y2() - titlebarH;
if (rect.y > limitB) {
rect.y = limitB;
rect.h = bounds().h;
}
int dx = rect.w - bounds().w;
auto limitL = border().right() - bounds().w;
if (rect.x + dx < limitL) {
rect.x = limitL;
rect.w = bounds().w;
}
auto limitR = parent()->bounds().x2() - border().right();
if (rect.x > limitR) {
rect.x = limitR;
rect.w = bounds().w;
}
} }
void Window::moveWindow(const gfx::Rect& rect, bool use_blit) void Window::moveWindow(const gfx::Rect& rect, bool use_blit)

View File

@ -117,7 +117,8 @@ namespace ui {
private: private:
void windowSetPosition(const gfx::Rect& rect); void windowSetPosition(const gfx::Rect& rect);
int getAction(int x, int y); int getAction(int x, int y);
void limitSize(int* w, int* h); void limitSize(gfx::Size& size);
void limitPosition(gfx::Rect& rect);
void moveWindow(const gfx::Rect& rect, bool use_blit); void moveWindow(const gfx::Rect& rect, bool use_blit);
Display* m_parentDisplay = nullptr; Display* m_parentDisplay = nullptr;