diff --git a/engine/client/console.c b/engine/client/console.c
index 1739d9716..131e3b900 100644
--- a/engine/client/console.c
+++ b/engine/client/console.c
@@ -23,6 +23,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
 console_t	con_main;
 console_t	*con_current;		// points to whatever is the visible console
+console_t	*con_mouseover;		// points to whichever console's title is currently mouseovered, or null
 console_t	*con_chat;			// points to a chat console
 conline_t *con_footerline;	//temp text at the bottom of the console
 
@@ -117,6 +118,8 @@ void Con_Destroy (console_t *con)
 		return;
 	}
 
+	con_mouseover = NULL;
+
 	for (prev = &con_main; prev->next; prev = prev->next)
 	{
 		if (prev->next == con)
@@ -1411,9 +1414,12 @@ static int Con_DrawProgress(int left, int right, int y)
 int Con_DrawAlternateConsoles(int lines)
 {
 	char *txt;
-	int x, y = 0;
+	int x, y = 0, lx;
 	int consshown = 0;
-	console_t *con = &con_main;
+	console_t *con = &con_main, *om = con_mouseover;
+	conchar_t buffer[512], *end, *start;
+
+	con_mouseover = NULL;
 
 	for (con = &con_main; con; con = con->next)
 	{
@@ -1423,6 +1429,10 @@ int Con_DrawAlternateConsoles(int lines)
 
 	if (lines == scr_conlines && consshown > 1) 
 	{
+		int mx, my, h;
+		Font_BeginString(font_conchar, mousecursor_x, mousecursor_y, &mx, &my);
+		Font_BeginString(font_conchar, 0, y, &x, &y);
+		h = Font_CharHeight();
 		for (x = 0, con = &con_main; con; con = con->next)
 		{
 			if (con->flags & CONF_HIDDEN)
@@ -1432,15 +1442,33 @@ int Con_DrawAlternateConsoles(int lines)
 			else
 				txt = con->name;
 
-			if (x != 0 && x+(strlen(txt)+1)*8 > vid.width)
+			//yeah, om is an evil 1-frame delay. whatever
+			end = COM_ParseFunString(CON_WHITEMASK, va("^&%c%i%s", ((con!=om)?'F':'B'), (con==con_current)+con->unseentext*4, txt), buffer, sizeof(buffer), false);
+
+			lx = 0;
+			for (lx = x, start = buffer; start < end; start++)
+			{
+				lx = Font_CharEndCoord(font_conchar, lx, *start);
+			}
+			if (lx > Font_ScreenWidth())
 			{
 				x = 0;
-				y += 8;
+				y += h;
 			}
-			Draw_FunString(x, y, va("^&F%i%s", (con==con_current)+con->unseentext*4, txt));
-			x+=(strlen(txt)+1)*8;
+			for (lx = x, start = buffer; start < end; start++)
+			{
+				Font_DrawChar(lx, y, *start);
+				lx = Font_CharEndCoord(font_conchar, lx, *start);
+			}
+			lx += 8;
+			if (mx >= x && mx < lx && my >= y && my < y+h)
+				con_mouseover = con;
+			x = lx;
 		}
-		y += 8;
+		y+= h;
+		Font_EndString(font_conchar);
+
+		y = (y*(int)vid.height) / (float)vid.rotpixelheight;
 	}
 	return y;
 }
diff --git a/engine/client/keys.c b/engine/client/keys.c
index 68dc8a799..6e4e72a7c 100644
--- a/engine/client/keys.c
+++ b/engine/client/keys.c
@@ -947,26 +947,12 @@ void Key_Console (unsigned int unicode, int key)
 		ypos = (int)((mousecursor_y*vid.height)/(vid.pixelheight*8));
 		con_mousedown[0] = mousecursor_x;
 		con_mousedown[1] = mousecursor_y;
-		if (ypos == 0 && con_main.next)
+		if (ypos == 0 && con_mouseover)
 		{
-			console_t *con;
-			for (con = &con_main; con; con = con->next)
-			{
-				if (con == &con_main)
-					xpos -= 5;
-				else
-					xpos -= strlen(con->name)+1;
-				if (xpos == -1)
-					break;
-				if (xpos < 0)
-				{
-					if (key == K_MOUSE2)
-						Con_Destroy (con);
-					else
-						con_current = con;
-					break;
-				}
-			}
+			if (key == K_MOUSE2)
+				Con_Destroy (con_mouseover);
+			else
+				con_current = con_mouseover;
 		}
 		else if (key == K_MOUSE2)
 			con_mousedown[2] = 2;
diff --git a/engine/common/console.h b/engine/common/console.h
index c19e4ca7b..e1c83983c 100644
--- a/engine/common/console.h
+++ b/engine/common/console.h
@@ -137,6 +137,7 @@ typedef struct console_s
 
 extern	console_t	con_main;
 extern	console_t	*con_current;			// point to either con_main or con_chat
+extern	console_t	*con_mouseover;
 extern	console_t	*con_chat;
 
 //shared between console and keys.