1
0
mirror of https://github.com/OpenTTD/OpenTTD synced 2026-01-16 17:02:37 +01:00

Fix a4dc7249ee: Changing language or interface scale could hang. (#14087)

A bit of hysteresis caused by OnResize calling ReInit calling OnResize calling ReInit calling OnResize calling ReInit ...
This commit is contained in:
Peter Nelson
2025-04-24 00:29:54 +01:00
committed by GitHub
parent 78d3eaf3e2
commit 7846f0f4ee
8 changed files with 46 additions and 43 deletions

View File

@@ -990,7 +990,7 @@ void Window::ReInit(int rx, int ry, bool reposition)
if (reposition) {
Point pt = this->OnInitialPosition(this->nested_root->smallest_x, this->nested_root->smallest_y, window_number);
this->InitializePositionSize(pt.x, pt.y, this->nested_root->smallest_x, this->nested_root->smallest_y);
this->FindWindowPlacementAndResize(this->window_desc.GetDefaultWidth(), this->window_desc.GetDefaultHeight());
this->FindWindowPlacementAndResize(this->window_desc.GetDefaultWidth(), this->window_desc.GetDefaultHeight(), false);
}
ResizeWindow(this, dx, dy, true, false);
@@ -1423,39 +1423,42 @@ void Window::InitializePositionSize(int x, int y, int sm_width, int sm_height)
* done here.
* @param def_width default width in pixels of the window
* @param def_height default height in pixels of the window
* @param allow_resize Set if resizing is permitted.
* @see Window::Window(), Window::InitializeData(), Window::InitializePositionSize()
*/
void Window::FindWindowPlacementAndResize(int def_width, int def_height)
void Window::FindWindowPlacementAndResize(int def_width, int def_height, bool allow_resize)
{
def_width = std::max(def_width, this->width); // Don't allow default size to be smaller than smallest size
def_height = std::max(def_height, this->height);
/* Try to make windows smaller when our window is too small.
* w->(width|height) is normally the same as min_(width|height),
* but this way the GUIs can be made a little more dynamic;
* one can use the same spec for multiple windows and those
* can then determine the real minimum size of the window. */
if (this->width != def_width || this->height != def_height) {
/* Think about the overlapping toolbars when determining the minimum window size */
int free_height = _screen.height;
const Window *wt = FindWindowById(WC_STATUS_BAR, 0);
if (wt != nullptr) free_height -= wt->height;
wt = FindWindowById(WC_MAIN_TOOLBAR, 0);
if (wt != nullptr) free_height -= wt->height;
if (allow_resize) {
def_width = std::max(def_width, this->width); // Don't allow default size to be smaller than smallest size
def_height = std::max(def_height, this->height);
/* Try to make windows smaller when our window is too small.
* w->(width|height) is normally the same as min_(width|height),
* but this way the GUIs can be made a little more dynamic;
* one can use the same spec for multiple windows and those
* can then determine the real minimum size of the window. */
if (this->width != def_width || this->height != def_height) {
/* Think about the overlapping toolbars when determining the minimum window size */
int free_height = _screen.height;
const Window *wt = FindWindowById(WC_STATUS_BAR, 0);
if (wt != nullptr) free_height -= wt->height;
wt = FindWindowById(WC_MAIN_TOOLBAR, 0);
if (wt != nullptr) free_height -= wt->height;
int enlarge_x = std::max(std::min(def_width - this->width, _screen.width - this->width), 0);
int enlarge_y = std::max(std::min(def_height - this->height, free_height - this->height), 0);
int enlarge_x = std::max(std::min(def_width - this->width, _screen.width - this->width), 0);
int enlarge_y = std::max(std::min(def_height - this->height, free_height - this->height), 0);
/* X and Y has to go by step.. calculate it.
* The cast to int is necessary else x/y are implicitly casted to
* unsigned int, which won't work. */
if (this->resize.step_width > 1) enlarge_x -= enlarge_x % (int)this->resize.step_width;
if (this->resize.step_height > 1) enlarge_y -= enlarge_y % (int)this->resize.step_height;
/* X and Y has to go by step.. calculate it.
* The cast to int is necessary else x/y are implicitly casted to
* unsigned int, which won't work. */
if (this->resize.step_width > 1) enlarge_x -= enlarge_x % (int)this->resize.step_width;
if (this->resize.step_height > 1) enlarge_y -= enlarge_y % (int)this->resize.step_height;
ResizeWindow(this, enlarge_x, enlarge_y, true, false);
/* ResizeWindow() calls this->OnResize(). */
} else {
/* Always call OnResize; that way the scrollbars and matrices get initialized. */
this->OnResize();
ResizeWindow(this, enlarge_x, enlarge_y, true, false);
/* ResizeWindow() calls this->OnResize(). */
} else {
/* Always call OnResize; that way the scrollbars and matrices get initialized. */
this->OnResize();
}
}
int nx = this->left;
@@ -1744,7 +1747,7 @@ void Window::FinishInitNested(WindowNumber window_number)
this->ApplyDefaults();
Point pt = this->OnInitialPosition(this->nested_root->smallest_x, this->nested_root->smallest_y, window_number);
this->InitializePositionSize(pt.x, pt.y, this->nested_root->smallest_x, this->nested_root->smallest_y);
this->FindWindowPlacementAndResize(this->window_desc.GetDefaultWidth(), this->window_desc.GetDefaultHeight());
this->FindWindowPlacementAndResize(this->window_desc.GetDefaultWidth(), this->window_desc.GetDefaultHeight(), true);
}
/**