From 2a0e2f16582e3c8a4fc37bc1638bb84c5bdcc777 Mon Sep 17 00:00:00 2001 From: Patric Stout Date: Sun, 4 Jun 2023 17:39:57 +0200 Subject: [PATCH] Fix: crash when window can't be placed on low resolution screens. (#10932) Co-authored-by: Jonathan G Rennison --- src/core/math_func.hpp | 26 ++++++++++++++++++++++++++ src/misc_gui.cpp | 4 ++-- 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/src/core/math_func.hpp b/src/core/math_func.hpp index 8f9b5626c9..7e65a51a43 100644 --- a/src/core/math_func.hpp +++ b/src/core/math_func.hpp @@ -82,6 +82,32 @@ static inline T Clamp(const T a, const T min, const T max) return a; } +/** + * Clamp a value between an interval. + * + * This function returns a value which is between the given interval of + * min and max. If the given value is in this interval the value itself + * is returned otherwise the border of the interval is returned, according + * which side of the interval was 'left'. + * + * @note If the min value is greater than the max, return value is the average of the min and max. + * @param a The value to clamp/truncate. + * @param min The minimum of the interval. + * @param max the maximum of the interval. + * @returns A value between min and max which is closest to a. + */ +template +static inline T SoftClamp(const T a, const T min, const T max) +{ + if (min > max) { + using U = std::make_unsigned_t; + return min - (U(min) - max) / 2; + } + if (a <= min) return min; + if (a >= max) return max; + return a; +} + /** * Clamp an integer between an interval. * diff --git a/src/misc_gui.cpp b/src/misc_gui.cpp index b3a5d3633b..89aaa86c54 100644 --- a/src/misc_gui.cpp +++ b/src/misc_gui.cpp @@ -1151,8 +1151,8 @@ struct QueryWindow : public Window { void FindWindowPlacementAndResize(int def_width, int def_height) override { /* Position query window over the calling window, ensuring it's within screen bounds. */ - this->left = Clamp(parent->left + (parent->width / 2) - (this->width / 2), 0, _screen.width - this->width); - this->top = Clamp(parent->top + (parent->height / 2) - (this->height / 2), 0, _screen.height - this->height); + this->left = SoftClamp(parent->left + (parent->width / 2) - (this->width / 2), 0, _screen.width - this->width); + this->top = SoftClamp(parent->top + (parent->height / 2) - (this->height / 2), 0, _screen.height - this->height); this->SetDirty(); }