changeset 18677:7077d1f6763b draft

(svn r23525) -Codechange: make Window::flags4 WindowFlags instead of uint16, with only values known in WindowFlags (and move out 2 timers to their own variable) -Codechange: rename Window::flags4 to Window::flags -Codechange: move some non-inline functions from .hpp to .cpp
author truebrain <truebrain@openttd.org>
date Thu, 15 Dec 2011 19:54:23 +0000
parents 9e9c2bc58ba0
children 5604c42fa1ce
files src/bootstrap_gui.cpp src/cheat_gui.cpp src/genworld_gui.cpp src/highscore_gui.cpp src/industry_gui.cpp src/main_gui.cpp src/misc_gui.cpp src/network/network_gui.cpp src/news_gui.cpp src/settings_gui.cpp src/station_gui.cpp src/statusbar_gui.cpp src/toolbar_gui.cpp src/town_gui.cpp src/tree_gui.cpp src/waypoint_gui.cpp src/widget.cpp src/widgets/dropdown.cpp src/window.cpp src/window_gui.h
diffstat 20 files changed, 132 insertions(+), 107 deletions(-) [+]
line wrap: on
line diff
--- a/src/bootstrap_gui.cpp
+++ b/src/bootstrap_gui.cpp
@@ -50,7 +50,7 @@
 	BootstrapBackground() : Window()
 	{
 		this->InitNested(&_background_desc, 0);
-		CLRBITS(this->flags4, WF_WHITE_BORDER_MASK);
+		CLRBITS(this->flags, WF_WHITE_BORDER);
 		ResizeWindow(this, _screen.width, _screen.height);
 	}
 
--- a/src/cheat_gui.cpp
+++ b/src/cheat_gui.cpp
@@ -360,7 +360,7 @@
 
 		if (value != oldvalue) WriteValue(ce->variable, ce->type, (int64)value);
 
-		this->flags4 |= WF_TIMEOUT_BEGIN;
+		this->SetTimeout();
 
 		this->SetDirty();
 	}
--- a/src/genworld_gui.cpp
+++ b/src/genworld_gui.cpp
@@ -639,7 +639,7 @@
 			case GLAND_START_DATE_DOWN:
 			case GLAND_START_DATE_UP: // Year buttons
 				/* Don't allow too fast scrolling */
-				if ((this->flags4 & WF_TIMEOUT_MASK) <= WF_TIMEOUT_TRIGGER) {
+				if ((this->flags & WF_TIMEOUT) && this->timeout_timer <= 1) {
 					this->HandleButtonClick(widget);
 
 					_settings_newgame.game_creation.starting_year = Clamp(_settings_newgame.game_creation.starting_year + widget - GLAND_START_DATE_TEXT, MIN_YEAR, MAX_YEAR);
@@ -657,7 +657,7 @@
 			case GLAND_SNOW_LEVEL_DOWN:
 			case GLAND_SNOW_LEVEL_UP: // Snow line buttons
 				/* Don't allow too fast scrolling */
-				if ((this->flags4 & WF_TIMEOUT_MASK) <= WF_TIMEOUT_TRIGGER) {
+				if ((this->flags & WF_TIMEOUT) && this->timeout_timer <= 1) {
 					this->HandleButtonClick(widget);
 
 					_settings_newgame.game_creation.snow_line_height = Clamp(_settings_newgame.game_creation.snow_line_height + widget - GLAND_SNOW_LEVEL_TEXT, MIN_SNOWLINE_HEIGHT, MAX_SNOWLINE_HEIGHT);
@@ -1049,7 +1049,7 @@
 			case CSCEN_START_DATE_DOWN:
 			case CSCEN_START_DATE_UP: // Year buttons
 				/* Don't allow too fast scrolling */
-				if ((this->flags4 & WF_TIMEOUT_MASK) <= WF_TIMEOUT_TRIGGER) {
+				if ((this->flags & WF_TIMEOUT) && this->timeout_timer <= 1) {
 					this->HandleButtonClick(widget);
 					this->SetDirty();
 
@@ -1067,7 +1067,7 @@
 			case CSCEN_FLAT_LAND_HEIGHT_DOWN:
 			case CSCEN_FLAT_LAND_HEIGHT_UP: // Height level buttons
 				/* Don't allow too fast scrolling */
-				if ((this->flags4 & WF_TIMEOUT_MASK) <= WF_TIMEOUT_TRIGGER) {
+				if ((this->flags & WF_TIMEOUT) && this->timeout_timer <= 1) {
 					this->HandleButtonClick(widget);
 					this->SetDirty();
 
--- a/src/highscore_gui.cpp
+++ b/src/highscore_gui.cpp
@@ -34,7 +34,7 @@
 	EndGameHighScoreBaseWindow(const WindowDesc *desc) : Window()
 	{
 		this->InitNested(desc);
-		CLRBITS(this->flags4, WF_WHITE_BORDER_MASK);
+		CLRBITS(this->flags, WF_WHITE_BORDER);
 		ResizeWindow(this, _screen.width - this->width, _screen.height - this->height);
 	}
 
--- a/src/industry_gui.cpp
+++ b/src/industry_gui.cpp
@@ -673,7 +673,7 @@
 public:
 	IndustryViewWindow(const WindowDesc *desc, WindowNumber window_number) : Window()
 	{
-		this->flags4 |= WF_DISABLE_VP_SCROLL;
+		this->flags |= WF_DISABLE_VP_SCROLL;
 		this->editbox_line = IL_NONE;
 		this->clicked_line = IL_NONE;
 		this->clicked_button = 0;
@@ -886,7 +886,7 @@
 
 					UpdateIndustryProduction(i);
 					this->SetDirty();
-					this->flags4 |= WF_TIMEOUT_BEGIN;
+					this->SetTimeout();
 					this->clicked_line = line;
 					this->clicked_button = button;
 				} else if (IsInsideMM(pt.x, left + 30, right)) {
--- a/src/main_gui.cpp
+++ b/src/main_gui.cpp
@@ -244,7 +244,7 @@
 	MainWindow() : Window()
 	{
 		this->InitNested(&_main_window_desc, 0);
-		CLRBITS(this->flags4, WF_WHITE_BORDER_MASK);
+		CLRBITS(this->flags, WF_WHITE_BORDER);
 		ResizeWindow(this, _screen.width, _screen.height);
 
 		NWidgetViewport *nvp = this->GetWidget<NWidgetViewport>(MW_VIEWPORT);
--- a/src/misc_gui.cpp
+++ b/src/misc_gui.cpp
@@ -643,7 +643,7 @@
 
 		this->InitNested(&_tool_tips_desc);
 
-		CLRBITS(this->flags4, WF_WHITE_BORDER_MASK); // remove white-border from tooltip
+		CLRBITS(this->flags, WF_WHITE_BORDER);
 	}
 
 	virtual Point OnInitialPosition(const WindowDesc *desc, int16 sm_width, int16 sm_height, int window_number)
--- a/src/network/network_gui.cpp
+++ b/src/network/network_gui.cpp
@@ -1156,7 +1156,7 @@
 			case NSSW_COMPANIES_BTND:  case NSSW_COMPANIES_BTNU:  // Click on up/down button for number of companies
 			case NSSW_SPECTATORS_BTND: case NSSW_SPECTATORS_BTNU: // Click on up/down button for number of spectators
 				/* Don't allow too fast scrolling */
-				if ((this->flags4 & WF_TIMEOUT_MASK) <= WF_TIMEOUT_TRIGGER) {
+				if ((this->flags & WF_TIMEOUT) && this->timeout_timer <= 1) {
 					this->HandleButtonClick(widget);
 					this->SetDirty();
 					switch (widget) {
@@ -1822,7 +1822,7 @@
 		}
 
 		this->InitNested(desc, client_id);
-		CLRBITS(this->flags4, WF_WHITE_BORDER_MASK);
+		CLRBITS(this->flags, WF_WHITE_BORDER);
 	}
 
 	virtual Point OnInitialPosition(const WindowDesc *desc, int16 sm_width, int16 sm_height, int window_number)
--- a/src/news_gui.cpp
+++ b/src/news_gui.cpp
@@ -293,7 +293,7 @@
 		this->chat_height = (w != NULL) ? w->height : 0;
 		this->status_height = FindWindowById(WC_STATUS_BAR, 0)->height;
 
-		this->flags4 |= WF_DISABLE_VP_SCROLL;
+		this->flags |= WF_DISABLE_VP_SCROLL;
 
 		this->CreateNestedTree(desc);
 		switch (this->ni->subtype) {
--- a/src/settings_gui.cpp
+++ b/src/settings_gui.cpp
@@ -1708,7 +1708,7 @@
 					if (step == 0) step = 1;
 
 					/* don't allow too fast scrolling */
-					if ((this->flags4 & WF_TIMEOUT_MASK) > WF_TIMEOUT_TRIGGER) {
+					if ((this->flags & WF_TIMEOUT) && this->timeout_timer > 1) {
 						_left_button_clicked = false;
 						return;
 					}
@@ -1735,7 +1735,7 @@
 						}
 						this->clicked_entry = pe;
 						this->clicked_entry->SetButtons((x >= 10) != (_current_text_dir == TD_RTL) ? SEF_RIGHT_DEPRESSED : SEF_LEFT_DEPRESSED);
-						this->flags4 |= WF_TIMEOUT_BEGIN;
+						this->SetTimeout();
 						_left_button_clicked = false;
 					}
 					break;
@@ -2016,7 +2016,7 @@
 			ShowQueryString(str, STR_CURRENCY_CHANGE_PARAMETER, len + 1, this, afilter, QSF_NONE);
 		}
 
-		this->flags4 |= WF_TIMEOUT_BEGIN;
+		this->SetTimeout();
 		this->SetDirty();
 	}
 
--- a/src/station_gui.cpp
+++ b/src/station_gui.cpp
@@ -596,7 +596,7 @@
 
 			case SLW_SORTBY: // flip sorting method asc/desc
 				this->stations.ToggleSortOrder();
-				this->flags4 |= WF_TIMEOUT_BEGIN;
+				this->SetTimeout();
 				this->LowerWidget(SLW_SORTBY);
 				this->SetDirty();
 				break;
--- a/src/statusbar_gui.cpp
+++ b/src/statusbar_gui.cpp
@@ -93,7 +93,7 @@
 		this->reminder_timeout = REMINDER_STOP;
 
 		this->InitNested(desc);
-		CLRBITS(this->flags4, WF_WHITE_BORDER_MASK);
+		CLRBITS(this->flags, WF_WHITE_BORDER);
 		PositionStatusbar(this);
 	}
 
--- a/src/toolbar_gui.cpp
+++ b/src/toolbar_gui.cpp
@@ -1094,7 +1094,7 @@
 static CallBackFunction ToolbarScenDateBackward(Window *w)
 {
 	/* don't allow too fast scrolling */
-	if ((w->flags4 & WF_TIMEOUT_MASK) <= WF_TIMEOUT_TRIGGER) {
+	if ((w->flags & WF_TIMEOUT) && w->timeout_timer <= 1) {
 		w->HandleButtonClick(TBSE_DATEBACKWARD);
 		w->SetDirty();
 
@@ -1108,7 +1108,7 @@
 static CallBackFunction ToolbarScenDateForward(Window *w)
 {
 	/* don't allow too fast scrolling */
-	if ((w->flags4 & WF_TIMEOUT_MASK) <= WF_TIMEOUT_TRIGGER) {
+	if ((w->flags & WF_TIMEOUT) && w->timeout_timer <= 1) {
 		w->HandleButtonClick(TBSE_DATEFORWARD);
 		w->SetDirty();
 
@@ -1566,7 +1566,7 @@
 		this->InitNested(desc, 0);
 
 		this->last_started_action = CBF_NONE;
-		CLRBITS(this->flags4, WF_WHITE_BORDER_MASK);
+		CLRBITS(this->flags, WF_WHITE_BORDER);
 		this->SetWidgetDisabledState(TBN_PAUSE, _networking && !_network_server); // if not server, disable pause button
 		this->SetWidgetDisabledState(TBN_FASTFORWARD, _networking); // if networking, disable fast-forward button
 		PositionMainToolbar(this);
@@ -1868,7 +1868,7 @@
 		this->InitNested(desc, 0);
 
 		this->last_started_action = CBF_NONE;
-		CLRBITS(this->flags4, WF_WHITE_BORDER_MASK);
+		CLRBITS(this->flags, WF_WHITE_BORDER);
 		PositionMainToolbar(this);
 		DoZoomInOutWindow(ZOOM_NONE, this);
 	}
--- a/src/town_gui.cpp
+++ b/src/town_gui.cpp
@@ -332,7 +332,7 @@
 
 		this->FinishInitNested(desc, window_number);
 
-		this->flags4 |= WF_DISABLE_VP_SCROLL;
+		this->flags|= WF_DISABLE_VP_SCROLL;
 		NWidgetViewport *nvp = this->GetWidget<NWidgetViewport>(TVW_VIEWPORT);
 		nvp->InitializeViewport(this, this->town->xy, ZOOM_LVL_NEWS);
 
--- a/src/tree_gui.cpp
+++ b/src/tree_gui.cpp
@@ -151,7 +151,7 @@
 
 			case BTW_MANY_RANDOM: // place trees randomly over the landscape
 				this->LowerWidget(BTW_MANY_RANDOM);
-				this->flags4 |= WF_TIMEOUT_BEGIN;
+				this->SetTimeout();
 				SndPlayFx(SND_15_BEEP);
 				PlaceTreesRandomly();
 				MarkWholeScreenDirty();
--- a/src/waypoint_gui.cpp
+++ b/src/waypoint_gui.cpp
@@ -73,7 +73,7 @@
 		this->FinishInitNested(desc, window_number);
 
 		if (this->wp->owner != OWNER_NONE) this->owner = this->wp->owner;
-		this->flags4 |= WF_DISABLE_VP_SCROLL;
+		this->flags |= WF_DISABLE_VP_SCROLL;
 
 		NWidgetViewport *nvp = this->GetWidget<NWidgetViewport>(WAYPVW_VIEWPORT);
 		nvp->InitializeViewport(this, this->GetCenterTile(), ZOOM_LVL_VIEWPORT);
--- a/src/widget.cpp
+++ b/src/widget.cpp
@@ -567,7 +567,7 @@
 {
 	this->nested_root->Draw(this);
 
-	if (this->flags4 & WF_WHITE_BORDER_MASK) {
+	if (this->flags & WF_WHITE_BORDER) {
 		DrawFrameRect(0, 0, this->width - 1, this->height - 1, COLOUR_WHITE, FR_BORDERONLY);
 	}
 }
@@ -2341,12 +2341,12 @@
 
 		case WWT_STICKYBOX:
 			assert(this->widget_data == 0);
-			DrawStickyBox(r, this->colour, !!(w->flags4 & WF_STICKY));
+			DrawStickyBox(r, this->colour, !!(w->flags & WF_STICKY));
 			break;
 
 		case WWT_RESIZEBOX:
 			assert(this->widget_data == 0);
-			DrawResizeBox(r, this->colour, this->pos_x < (uint)(w->width / 2), !!(w->flags4 & WF_SIZING));
+			DrawResizeBox(r, this->colour, this->pos_x < (uint)(w->width / 2), !!(w->flags & WF_SIZING));
 			break;
 
 		case WWT_CLOSEBOX:
--- a/src/widgets/dropdown.cpp
+++ b/src/widgets/dropdown.cpp
@@ -148,7 +148,7 @@
 		this->GetWidget<NWidgetStacked>(DDM_SHOW_SCROLL)->SetDisplayedPlane(scroll ? 0 : SZSP_NONE);
 
 		this->FinishInitNested(&_dropdown_desc, 0);
-		CLRBITS(this->flags4, WF_WHITE_BORDER_MASK);
+		CLRBITS(this->flags, WF_WHITE_BORDER);
 
 		/* Total length of list */
 		int list_height = 0;
--- a/src/window.cpp
+++ b/src/window.cpp
@@ -264,7 +264,7 @@
 void Window::HandleButtonClick(byte widget)
 {
 	this->LowerWidget(widget);
-	this->flags4 |= WF_TIMEOUT_BEGIN;
+	this->SetTimeout();
 	this->SetWidgetDirty(widget);
 }
 
@@ -373,7 +373,7 @@
 			return;
 
 		case WWT_STICKYBOX:
-			w->flags4 ^= WF_STICKY;
+			w->flags ^= WF_STICKY;
 			nw->SetDirty(w);
 			return;
 
@@ -753,7 +753,7 @@
 {
 	Window *w = FindWindowById(cls, number);
 	if (force || w == NULL ||
-			(w->flags4 & WF_STICKY) == 0) {
+			(w->flags & WF_STICKY) == 0) {
 		delete w;
 	}
 }
@@ -852,7 +852,7 @@
 	if (w != NULL) {
 		if (w->IsShaded()) w->SetShaded(false); // Restore original window size if it was shaded.
 
-		w->flags4 |= WF_WHITE_BORDER_MASK;
+		w->SetWhiteBorder();
 		BringWindowToFront(w);
 		w->SetDirty();
 	}
@@ -1037,8 +1037,8 @@
 {
 	/* Set up window properties; some of them are needed to set up smallest size below */
 	this->window_class = desc->cls;
-	this->flags4 |= WF_WHITE_BORDER_MASK; // just opened windows have a white border
-	if (desc->default_pos == WDP_CENTER) this->flags4 |= WF_CENTERED;
+	this->SetWhiteBorder();
+	if (desc->default_pos == WDP_CENTER) this->flags |= WF_CENTERED;
 	this->owner = INVALID_OWNER;
 	this->nested_focus = NULL;
 	this->window_number = window_number;
@@ -1506,7 +1506,9 @@
 	}
 
 	FOR_ALL_WINDOWS_FROM_FRONT(w) {
-		if ((w->flags4 & WF_TIMEOUT_MASK) && !(--w->flags4 & WF_TIMEOUT_MASK)) {
+		if ((w->flags & WF_TIMEOUT) && --w->timeout_timer == 0) {
+			CLRBITS(w->flags, WF_TIMEOUT);
+
 			w->OnTimeout();
 			if (w->desc_flags & WDF_UNCLICK_BUTTONS) w->RaiseButtons(true);
 		}
@@ -1742,10 +1744,10 @@
 	/* Otherwise find the window... */
 	Window *w;
 	FOR_ALL_WINDOWS_FROM_BACK(w) {
-		if (w->flags4 & WF_DRAGGING) {
+		if (w->flags & WF_DRAGGING) {
 			/* Stop the dragging if the left mouse button was released */
 			if (!_left_button_down) {
-				w->flags4 &= ~WF_DRAGGING;
+				w->flags &= ~WF_DRAGGING;
 				break;
 			}
 
@@ -1836,10 +1838,10 @@
 
 			w->SetDirty();
 			return ES_HANDLED;
-		} else if (w->flags4 & WF_SIZING) {
+		} else if (w->flags & WF_SIZING) {
 			/* Stop the sizing if the left mouse button was released */
 			if (!_left_button_down) {
-				w->flags4 &= ~WF_SIZING;
+				w->flags &= ~WF_SIZING;
 				w->SetDirty();
 				break;
 			}
@@ -1848,7 +1850,7 @@
 			 * If resizing the left edge of the window, moving to the left makes the window bigger not smaller.
 			 */
 			int x, y = _cursor.pos.y - _drag_delta.y;
-			if (w->flags4 & WF_SIZING_LEFT) {
+			if (w->flags & WF_SIZING_LEFT) {
 				x = _drag_delta.x - _cursor.pos.x;
 			} else {
 				x = _cursor.pos.x - _drag_delta.x;
@@ -1882,7 +1884,7 @@
 
 			/* Now find the new cursor pos.. this is NOT _cursor, because we move in steps. */
 			_drag_delta.y += y;
-			if ((w->flags4 & WF_SIZING_LEFT) && x != 0) {
+			if ((w->flags & WF_SIZING_LEFT) && x != 0) {
 				_drag_delta.x -= x; // x > 0 -> window gets longer -> left-edge moves to left -> subtract x to get new position.
 				w->SetDirty();
 				w->left -= x;  // If dragging left edge, move left window edge in opposite direction by the same amount.
@@ -1907,8 +1909,8 @@
  */
 static void StartWindowDrag(Window *w)
 {
-	w->flags4 |= WF_DRAGGING;
-	w->flags4 &= ~WF_CENTERED;
+	w->flags |= WF_DRAGGING;
+	w->flags &= ~WF_CENTERED;
 	_dragging_window = true;
 
 	_drag_delta.x = w->left - _cursor.pos.x;
@@ -1925,8 +1927,8 @@
  */
 static void StartWindowSizing(Window *w, bool to_left)
 {
-	w->flags4 |= to_left ? WF_SIZING_LEFT : WF_SIZING_RIGHT;
-	w->flags4 &= ~WF_CENTERED;
+	w->flags |= to_left ? WF_SIZING_LEFT : WF_SIZING_RIGHT;
+	w->flags &= ~WF_CENTERED;
 	_dragging_window = true;
 
 	_drag_delta.x = _cursor.pos.x;
@@ -2073,7 +2075,7 @@
 	FOR_ALL_WINDOWS_FROM_BACK_FROM(u, w->z_front) {
 		/* A modal child will prevent the activation of the parent window */
 		if (u->parent == w && (u->desc_flags & WDF_MODAL)) {
-			u->flags4 |= WF_WHITE_BORDER_MASK;
+			u->SetWhiteBorder();
 			u->SetDirty();
 			return false;
 		}
@@ -2178,7 +2180,7 @@
 		int x = _cursor.pos.x;
 		int y = _cursor.pos.y;
 		Window *w = FindWindowFromPt(x, y);
-		if (w == NULL || w->flags4 & WF_DISABLE_VP_SCROLL) return;
+		if (w == NULL || w->flags & WF_DISABLE_VP_SCROLL) return;
 		ViewPort *vp = IsPtInWindowViewport(w, x, y);
 		if (vp != NULL) {
 			x -= vp->left;
@@ -2311,7 +2313,7 @@
 			case MC_LEFT:
 				DEBUG(misc, 2, "Cursor: 0x%X (%d)", _cursor.sprite, _cursor.sprite);
 				if (!HandleViewportClicked(vp, x, y) &&
-						!(w->flags4 & WF_DISABLE_VP_SCROLL) &&
+						!(w->flags & WF_DISABLE_VP_SCROLL) &&
 						_settings_client.gui.left_mouse_btn_scrolling) {
 					_scrolling_viewport = true;
 					_cursor.fix_at = false;
@@ -2319,7 +2321,7 @@
 				break;
 
 			case MC_RIGHT:
-				if (!(w->flags4 & WF_DISABLE_VP_SCROLL)) {
+				if (!(w->flags & WF_DISABLE_VP_SCROLL)) {
 					_scrolling_viewport = true;
 					_cursor.fix_at = true;
 
@@ -2445,7 +2447,7 @@
 		uint deletable_count = 0;
 		Window *w, *last_deletable = NULL;
 		FOR_ALL_WINDOWS_FROM_FRONT(w) {
-			if (w->window_class == WC_MAIN_WINDOW || IsVitalWindow(w) || (w->flags4 & WF_STICKY)) continue;
+			if (w->window_class == WC_MAIN_WINDOW || IsVitalWindow(w) || (w->flags & WF_STICKY)) continue;
 
 			last_deletable = w;
 			deletable_count++;
@@ -2520,10 +2522,9 @@
 	we4_timer = t;
 
 	FOR_ALL_WINDOWS_FROM_FRONT(w) {
-		if (w->flags4 & WF_WHITE_BORDER_MASK) {
-			w->flags4 -= WF_WHITE_BORDER_ONE;
-
-			if (!(w->flags4 & WF_WHITE_BORDER_MASK)) w->SetDirty();
+		if ((w->flags & WF_WHITE_BORDER) && --w->white_border_timer == 0) {
+			CLRBITS(w->flags, WF_WHITE_BORDER);
+			w->SetDirty();
 		}
 	}
 
@@ -2580,6 +2581,32 @@
 }
 
 /**
+ * Mark this window's data as invalid (in need of re-computing)
+ * @param data The data to invalidate with
+ * @param gui_scope Whether the funtion is called from GUI scope.
+ */
+void Window::InvalidateData(int data, bool gui_scope)
+{
+	this->SetDirty();
+	if (!gui_scope) {
+		/* Schedule GUI-scope invalidation for next redraw. */
+		*this->scheduled_invalidation_data.Append() = data;
+	}
+	this->OnInvalidateData(data, gui_scope);
+}
+
+/**
+ * Process all scheduled invalidations.
+ */
+void Window::ProcessScheduledInvalidations()
+{
+	for (int *data = this->scheduled_invalidation_data.Begin(); this->window_class != WC_INVALID && data != this->scheduled_invalidation_data.End(); data++) {
+		this->OnInvalidateData(*data, true);
+	}
+	this->scheduled_invalidation_data.Clear();
+}
+
+/**
  * Mark window data of the window of a given class and specific window number as invalid (in need of re-computing)
  *
  * Note that by default the invalidation is not considered to be called from GUI scope.
@@ -2665,7 +2692,7 @@
 				w->window_class != WC_MAIN_TOOLBAR &&
 				w->window_class != WC_STATUS_BAR &&
 				w->window_class != WC_TOOLTIPS &&
-				(w->flags4 & WF_STICKY) == 0) { // do not delete windows which are 'pinned'
+				(w->flags & WF_STICKY) == 0) { // do not delete windows which are 'pinned'
 
 			delete w;
 			goto restart_search;
@@ -2692,7 +2719,7 @@
 	 * as deleting this window could cascade in deleting (many) others
 	 * anywhere in the z-array */
 	FOR_ALL_WINDOWS_FROM_BACK(w) {
-		if (w->flags4 & WF_STICKY) {
+		if (w->flags & WF_STICKY) {
 			delete w;
 			goto restart_search;
 		}
@@ -2893,7 +2920,7 @@
 				continue;
 
 			default: {
-				if (w->flags4 & WF_CENTERED) {
+				if (w->flags & WF_CENTERED) {
 					top = (newh - w->height) >> 1;
 					left = (neww - w->width) >> 1;
 					break;
--- a/src/window_gui.h
+++ b/src/window_gui.h
@@ -206,6 +206,27 @@
 };
 
 /**
+ * Window flags.
+ */
+enum WindowFlags {
+	WF_TIMEOUT           = 1 <<  0, ///< Window timeout counter.
+
+	WF_DRAGGING          = 1 <<  3, ///< Window is being dragged.
+	WF_SIZING_RIGHT      = 1 <<  4, ///< Window is being resized towards the right.
+	WF_SIZING_LEFT       = 1 <<  5, ///< Window is being resized towards the left.
+	WF_SIZING            = WF_SIZING_RIGHT | WF_SIZING_LEFT, ///< Window is being resized.
+	WF_STICKY            = 1 <<  6, ///< Window is made sticky by user
+	WF_DISABLE_VP_SCROLL = 1 <<  7, ///< Window does not do autoscroll, @see HandleAutoscroll().
+	WF_WHITE_BORDER      = 1 <<  8, ///< Window white border counter bit mask.
+
+	WF_CENTERED          = 1 << 10, ///< Window is centered and shall stay centered after ReInit.
+};
+DECLARE_ENUM_AS_BIT_SET(WindowFlags)
+
+static const int TIMEOUT_DURATION = 7; ///< The initial timeout value for WF_TIMEOUT.
+static const int WHITE_BORDER_DURATION = 3; ///< The initial timeout value for WF_WHITE_BORDER.
+
+/**
  * Data structure for a window viewport.
  * A viewport is either following a vehicle (its id in then in #follow_vehicle), or it aims to display a specific
  * location #dest_scrollpos_x, #dest_scrollpos_y (#follow_vehicle is then #INVALID_VEHICLE).
@@ -256,10 +277,13 @@
 	{
 	}
 
-	uint16 flags4;              ///< Window flags, @see WindowFlags
+	WindowFlags flags;          ///< Window flags
 	WindowClass window_class;   ///< Window class
 	WindowNumber window_number; ///< Window number within the window class
 
+	uint8 timeout_timer;      ///< Timer value of the WF_TIMEOUT for flags.
+	uint8 white_border_timer; ///< Timervalue of the WF_WHITE_BORDER for flags.
+
 	int left;   ///< x position of left edge of the window
 	int top;    ///< y position of top edge of the window
 	int width;  ///< width of the window (number of pixels to the right in x direction)
@@ -278,7 +302,7 @@
 	NWidgetStacked *shade_select;    ///< Selection widget (#NWID_SELECTION) to use for shading the window. If \c NULL, window cannot shade.
 	Dimension unshaded_size;         ///< Last known unshaded size (only valid while shaded).
 
-	int scrolling_scrollbar;         ///< Widgetindex of just being dragged scrollbar. -1 of none is active.
+	int scrolling_scrollbar;         ///< Widgetindex of just being dragged scrollbar. -1 if none is active.
 
 	Window *parent;                  ///< Parent window.
 	Window *z_front;                 ///< The window in front of us in z-order.
@@ -297,6 +321,24 @@
 	void FinishInitNested(const WindowDesc *desc, WindowNumber window_number = 0);
 
 	/**
+	 * Set the timeout flag of the window and initiate the timer.
+	 */
+	inline void SetTimeout()
+	{
+		this->flags |= WF_TIMEOUT;
+		this->timeout_timer = TIMEOUT_DURATION;
+	}
+
+	/**
+	 * Set the timeout flag of the window and initiate the timer.
+	 */
+	inline void SetWhiteBorder()
+	{
+		this->flags |= WF_WHITE_BORDER;
+		this->white_border_timer = WHITE_BORDER_DURATION;
+	}
+
+	/**
 	 * Sets the enabled/disabled status of a widget.
 	 * By default, widgets are enabled.
 	 * On certain conditions, they have to be disabled.
@@ -438,31 +480,8 @@
 
 	void SetShaded(bool make_shaded);
 
-	/**
-	 * Mark this window's data as invalid (in need of re-computing)
-	 * @param data The data to invalidate with
-	 * @param gui_scope Whether the funtion is called from GUI scope.
-	 */
-	void InvalidateData(int data = 0, bool gui_scope = true)
-	{
-		this->SetDirty();
-		if (!gui_scope) {
-			/* Schedule GUI-scope invalidation for next redraw. */
-			*this->scheduled_invalidation_data.Append() = data;
-		}
-		this->OnInvalidateData(data, gui_scope);
-	}
-
-	/**
-	 * Process all scheduled invalidations.
-	 */
-	void ProcessScheduledInvalidations()
-	{
-		for (int *data = this->scheduled_invalidation_data.Begin(); this->window_class != WC_INVALID && data != this->scheduled_invalidation_data.End(); data++) {
-			this->OnInvalidateData(*data, true);
-		}
-		this->scheduled_invalidation_data.Clear();
-	}
+	void InvalidateData(int data = 0, bool gui_scope = true);
+	void ProcessScheduledInvalidations();
 
 	/*** Event handling ***/
 
@@ -773,27 +792,6 @@
 	virtual ~PickerWindowBase();
 };
 
-/**
- * Window flags
- */
-enum WindowFlags {
-	WF_TIMEOUT_TRIGGER   = 1,       ///< When the timeout should start triggering
-	WF_TIMEOUT_BEGIN     = 7,       ///< The initial value for the timeout
-	WF_TIMEOUT_MASK      = 7,       ///< Window timeout counter bit mask (3 bits)
-	WF_DRAGGING          = 1 <<  3, ///< Window is being dragged
-	WF_SIZING_RIGHT      = 1 <<  4, ///< Window is being resized towards the right.
-	WF_SIZING_LEFT       = 1 <<  5, ///< Window is being resized towards the left.
-	WF_SIZING            = WF_SIZING_RIGHT | WF_SIZING_LEFT, ///< Window is being resized.
-	WF_STICKY            = 1 <<  6, ///< Window is made sticky by user
-
-	WF_DISABLE_VP_SCROLL = 1 <<  7, ///< Window does not do autoscroll, @see HandleAutoscroll()
-
-	WF_WHITE_BORDER_ONE  = 1 <<  8,
-	WF_WHITE_BORDER_MASK = 1 <<  9 | WF_WHITE_BORDER_ONE,
-
-	WF_CENTERED          = 1 << 10, ///< Window is centered and shall stay centered after ReInit
-};
-
 Window *BringWindowToFrontById(WindowClass cls, WindowNumber number);
 Window *FindWindowFromPt(int x, int y);