From c81a333cb60dfda9e3fa35db1fa19e35b638299c Mon Sep 17 00:00:00 2001
From: rubidium <rubidium@openttd.org>
Date: Thu, 15 May 2008 20:52:28 +0000
Subject: [PATCH] (svn r13110) -Fix [FS#2018]: some toolbar buttons not being
 unpressed properly.

---
 src/viewport.cpp  | 17 ++++++++++-------
 src/window_type.h |  2 ++
 2 files changed, 12 insertions(+), 7 deletions(-)

diff --git a/src/viewport.cpp b/src/viewport.cpp
index 10369e1ec9..f090a7565c 100644
--- a/src/viewport.cpp
+++ b/src/viewport.cpp
@@ -2708,11 +2708,18 @@ void SetObjectToPlaceWnd(CursorID icon, SpriteID pal, ViewportHighlightMode mode
 
 void SetObjectToPlace(CursorID icon, SpriteID pal, ViewportHighlightMode mode, WindowClass window_class, WindowNumber window_num)
 {
-	Window *w = NULL;
-
 	/* undo clicking on button and drag & drop */
 	if (_thd.place_mode != VHM_NONE || _special_mouse_mode == WSM_DRAGDROP) {
-		w = FindWindowById(_thd.window_class, _thd.window_number);
+		Window *w = FindWindowById(_thd.window_class, _thd.window_number);
+		if (w != NULL) {
+			/* Call the abort function, but set the window class to something
+			 * that will never be used to avoid infinite loops. Setting it to
+			 * the 'next' window class must not be done because recursion into
+			 * this function might in some cases reset the newly set object to
+			 * place or not properly reset the original selection. */
+			_thd.window_class = WC_INVALID;
+			w->OnPlaceObjectAbort();
+		}
 	}
 
 	SetTileSelectSize(1, 1);
@@ -2739,10 +2746,6 @@ void SetObjectToPlace(CursorID icon, SpriteID pal, ViewportHighlightMode mode, W
 		SetMouseCursor(icon, pal);
 	}
 
-	/* Call the abort function only *after* the window class/number
-	 * are reset so one doesn't get into infinite loops when someone
-	 * resets the object to place during the abort callback. */
-	if (w != NULL) w->OnPlaceObjectAbort();
 }
 
 void ResetObjectToPlace()
diff --git a/src/window_type.h b/src/window_type.h
index f1952d1d5b..86071a8304 100644
--- a/src/window_type.h
+++ b/src/window_type.h
@@ -94,6 +94,8 @@ enum WindowClass {
 	WC_BUILD_SIGNAL,
 	WC_COMPANY_PASSWORD_WINDOW,
 	WC_OSK,
+
+	WC_INVALID = 0xFFFF
 };
 
 struct Window;