diff --git a/src/conio/bitmap_con.c b/src/conio/bitmap_con.c
index eb4e1cc2a7ad652740a2c57bf03ab69966804287..c4496bfede86182889f1b8c4e61d083b825f670a 100644
--- a/src/conio/bitmap_con.c
+++ b/src/conio/bitmap_con.c
@@ -1,6 +1,8 @@
 /* $Id: bitmap_con.c,v 1.148 2020/06/27 00:04:44 deuce Exp $ */
 
+#include <math.h>
 #include <stdarg.h>
+#include <stdbool.h>
 #include <stdio.h>		/* NULL */
 #include <stdlib.h>
 #include <string.h>
@@ -1612,6 +1614,64 @@ static int init_screens(int *width, int *height)
 /* Called from drivers */
 /***********************/
 
+// Must be called with vstatlock
+static void
+get_scaled_win_size(int scale, bool wc, int *w, int *h, int maxwidth, int maxheight)
+{
+	*w = vstat.scrnwidth * scale;
+	*h = vstat.scrnheight * scale;
+	if (wc)
+		*h = INT_MAX;
+	else
+		*w = INT_MAX;
+	if (*w > maxwidth && maxwidth > 0)
+		*w = maxwidth;
+	if (*h > maxheight && maxheight > 0)
+		*h = maxheight;
+	aspect_fix_wc(w, h, wc, vstat.aspect_width, vstat.aspect_height);
+}
+
+// Must be called with vstatlock
+void
+bitmap_snap(bool grow, int maxwidth, int maxheight)
+{
+	int mult;
+	int wc;
+	int cw;
+	int cs;
+	int w, h;
+
+	w = vstat.winwidth;
+	h = vstat.winheight;
+	if (vstat.aspect_width == 0 || vstat.aspect_height == 0)
+		wc = true;
+	else
+		wc = lround((double)(vstat.scrnheight * vstat.aspect_width) / vstat.aspect_height) <= vstat.scrnwidth;
+	if (wc) {
+		mult = vstat.winwidth / vstat.scrnwidth;
+		cw = vstat.winwidth;
+		cs = vstat.scrnwidth;
+	}
+	else {
+		mult = vstat.winheight / vstat.scrnheight;
+		cw = vstat.winheight;
+		cs = vstat.winwidth;
+	}
+	if (grow) {
+		mult++;
+	}
+	else {
+		if (cw % cs == 0)
+			mult--;
+	}
+	if (mult < 1)
+		mult = 1;
+	do {
+		get_scaled_win_size(mult, wc, &vstat.winwidth, &vstat.winheight, maxwidth, maxheight);
+		mult--;
+	} while ((vstat.winwidth > maxwidth || vstat.winheight > maxheight) && mult > 1);
+}
+
 /*
  * This function is intended to be called from the driver.
  * as a result, it cannot block waiting for driver status
@@ -1624,9 +1684,16 @@ static int init_screens(int *width, int *height)
  * out after this and only grab that lock again briefly to update
  * vstat.scaling.
  */
-int bitmap_drv_init_mode(int mode, int *width, int *height)
+int bitmap_drv_init_mode(int mode, int *width, int *height, int maxwidth, int maxheight)
 {
 	int i;
+	int64_t os;
+	int64_t ls;
+	int64_t ns;
+	int64_t bs;
+	int w, h;
+	int mult;
+	bool wc;
 
 	if(!bitmap_initialized)
 		return(-1);
@@ -1635,6 +1702,9 @@ int bitmap_drv_init_mode(int mode, int *width, int *height)
 		return(-1);
 	}
 
+	// Save the old diagonal (no point is sqrting here)
+	os = ((int64_t)vstat.winwidth * vstat.winwidth) + ((int64_t)vstat.winheight * vstat.winheight);
+
 	/* Initialize video memory with black background, white foreground */
 	for (i = 0; i < vstat.cols*vstat.rows; ++i) {
 		if (i > 0)
@@ -1674,6 +1744,41 @@ int bitmap_drv_init_mode(int mode, int *width, int *height)
 	cio_textinfo.winright=cio_textinfo.screenwidth;
 	cio_textinfo.winbottom=cio_textinfo.screenheight;
 
+	// Now calculate the closest diagonal new size that's smaller than max...
+	if (vstat.aspect_width == 0 || vstat.aspect_height == 0)
+		wc = true;
+	else
+		wc = lround((double)(vstat.scrnheight * vstat.aspect_width) / vstat.aspect_height) <= vstat.scrnwidth;
+	mult = 1;
+	get_scaled_win_size(mult, wc, &w, &h, maxwidth, maxheight);
+	bs = ((int64_t)w * w) + ((int64_t)h * h);
+	ls = bs;
+	ns = bs;
+	while (ns < os) {
+		mult++;
+		get_scaled_win_size(mult, wc, &w, &h, maxwidth, maxheight);
+		if ((maxwidth > 0) && (w > maxwidth)) {
+			mult--;
+			ns = ls;
+			break;
+		}
+		if ((maxheight > 0) && (h > maxheight)) {
+			mult--;
+			ns = ls;
+			break;
+		}
+		bs = ((int64_t)w * w) + ((int64_t)h * h);
+		ls = ns;
+		ns = bs;
+	}
+	if ((os - ls) <= (ns - os)) {
+		if (mult > 1)
+			mult--;
+	}
+	get_scaled_win_size(mult, wc, &w, &h, maxwidth, maxheight);
+	vstat.winwidth = w;
+	vstat.winheight = h;
+
 	return(0);
 }
 
diff --git a/src/conio/bitmap_con.h b/src/conio/bitmap_con.h
index 3e104604cd3bdf9316e6816576441c5268972797..4e5c74be7a7f6fb83b3f3c6d219fd1d5962b0869 100644
--- a/src/conio/bitmap_con.h
+++ b/src/conio/bitmap_con.h
@@ -50,12 +50,13 @@ int bitmap_setpalette(uint32_t index, uint16_t r, uint16_t g, uint16_t b);
 
 #ifdef BITMAP_CIOLIB_DRIVER
 /* Called from drivers */
-int bitmap_drv_init_mode(int mode, int *width, int *height);
+int bitmap_drv_init_mode(int mode, int *width, int *height, int maxwidth, int maxheight);
 int bitmap_drv_init(void (*drawrect_cb) (struct rectlist *data)
 				,void (*flush) (void));
 void bitmap_drv_request_pixels(void);
 void bitmap_drv_request_some_pixels(int x, int y, int width, int height);
 void bitmap_drv_free_rect(struct rectlist *rect);
+void bitmap_snap(bool grow, int maxwidth, int maxheight);
 #endif
 
 #endif
diff --git a/src/conio/scale.c b/src/conio/scale.c
index c5fdf2c3bbb62c3f17d18a160745b6f0ab59d2bb..9948c27c6993399b5ee9dcd72b566200f5c3384e 100644
--- a/src/conio/scale.c
+++ b/src/conio/scale.c
@@ -26,6 +26,32 @@ static struct graphics_buffer *free_list;
 		x = 255; \
 } while(0)
 
+/*
+ * Corrects width/height to have the specified aspect ratio
+ * any fit inside the specified rectangle
+ */
+void
+aspect_fix_wc(int *x, int *y, bool wc, int aspect_width, int aspect_height)
+{
+	int bestx, besty;
+
+	if (aspect_width == 0 || aspect_height == 0)
+		return;
+	if (r2yptr != NULL && y2rptr != NULL) {
+		bestx = lround((double)*y * aspect_width / aspect_height);
+		besty = lround((double)*x * aspect_height / aspect_width);
+	}
+	else {
+		bestx = lround((double)*y * *x / *y);
+		besty = lround((double)*x * *y / *x);
+	}
+
+	if (wc)
+		*y = besty;
+	else
+		*x = bestx;
+}
+
 /*
  * Corrects width/height to have the specified aspect ratio
  * any fit inside the specified rectangle
diff --git a/src/conio/scale.h b/src/conio/scale.h
index 4ce37c55a0c8fc3279aed44b39e6869184cecd32..3b127a255351312f71f705de56f4f84851e072b9 100644
--- a/src/conio/scale.h
+++ b/src/conio/scale.h
@@ -1,3 +1,5 @@
+#include <stdbool.h>
+
 #include "bitmap_con.h"
 
 struct graphics_buffer {
@@ -19,6 +21,7 @@ struct graphics_buffer * do_scale(struct rectlist* rect, int xscale, int yscale,
 void aspect_correct(int *x, int *y, int aspect_width, int aspect_height);
 void aspect_reverse(int *x, int *y, int scrnwidth, int scrnheight, int aspect_width, int aspect_height);
 void aspect_fix(int *x, int *y, int aspect_width, int aspect_height);
+void aspect_fix_wc(int *x, int *y, bool wc, int aspect_width, int aspect_height);
 void aspect_fix_low(int *x, int *y, int aspect_width, int aspect_height);
 void calc_scaling_factors(int *x, int *y, int winwidth, int winheight, int aspect_width, int aspect_height, int scrnwidth, int scrnheight);
 void aspect_fix_inside(int *x, int *y, int aspect_width, int aspect_height);
diff --git a/src/conio/sdl_con.c b/src/conio/sdl_con.c
index fc3791a009c9819048ea0c26825a8b5f24535d9f..bce078d802c539c7f21a619421b35e67a806d0c7 100644
--- a/src/conio/sdl_con.c
+++ b/src/conio/sdl_con.c
@@ -359,6 +359,8 @@ static int sdl_init_mode(int mode)
 {
 	int oldcols;
 	int scaling = 1;
+	int w, h;
+	SDL_Rect r;
 
 	if (mode != CIOLIB_MODE_CUSTOM) {
 		pthread_mutex_lock(&vstatlock);
@@ -373,37 +375,15 @@ static int sdl_init_mode(int mode)
 
 	pthread_mutex_lock(&vstatlock);
 	oldcols = vstat.cols;
-	bitmap_drv_init_mode(mode, &bitmap_width, &bitmap_height);
-	if (vstat.scrnwidth > 0) {
-		for (scaling = 1; (scaling + 1) * vstat.scrnwidth < vstat.winwidth; scaling++)
-			;
+	if (sdl.GetDisplayUsableBounds(0, &r) == 0) {
+		w = r.w;
+		h = r.h;
 	}
-	vstat.winwidth = vstat.scrnwidth * scaling;
-	vstat.winheight = vstat.scrnheight * scaling;
-	aspect_fix(&vstat.winwidth, &vstat.winheight, vstat.aspect_width, vstat.aspect_height);
-	if (oldcols != vstat.cols) {
-		if (oldcols == 0) {
-			if (ciolib_initial_window_width > 0)
-				vstat.winwidth = ciolib_initial_window_width;
-			if (ciolib_initial_window_height > 0)
-				vstat.winheight = ciolib_initial_window_height;
-			if (vstat.cols == 40)
-				oldcols = 40;
-		}
-		if (oldcols == 40) {
-			vstat.winwidth /= 2;
-			vstat.winheight /= 2;
-		}
-		if (vstat.cols == 40) {
-			vstat.winwidth *= 2;
-			vstat.winheight *= 2;
-		}
+	else {
+		w = 0;
+		h = 0;
 	}
-	if (vstat.winwidth < vstat.scrnwidth)
-		vstat.winwidth = vstat.scrnwidth;
-	if (vstat.winheight < vstat.scrnheight)
-		vstat.winheight = vstat.scrnheight;
-
+	bitmap_drv_init_mode(mode, &bitmap_width, &bitmap_height, w, h);
 	internal_scaling = window_can_scale_internally(&vstat);
 	pthread_mutex_lock(&sdl_mode_mutex);
 	sdl_mode = true;
@@ -891,62 +871,22 @@ void sdl_video_event_thread(void *data)
 					if ((ev.key.keysym.mod & KMOD_ALT) &&
 					    (ev.key.keysym.sym == SDLK_LEFT ||
 					     ev.key.keysym.sym == SDLK_RIGHT)) {
-						int w, h;
-
 						// Don't allow ALT-DIR to change size when maximized...
 						if ((sdl.GetWindowFlags(win) & SDL_WINDOW_MAXIMIZED) == 0) {
-							bool wc;
-
-							update_cvstat(&cvstat);
-							w = cvstat.winwidth;
-							h = cvstat.winheight;
-							aspect_fix(&w, &h, cvstat.aspect_width, cvstat.aspect_height);
-							if (cvstat.aspect_width == 0 || cvstat.aspect_height == 0)
-								wc = true;
-							else
-								wc = lround((double)(h * cvstat.aspect_width) / cvstat.aspect_height * cvstat.scrnwidth / cvstat.scrnheight) > w;
-							switch(ev.key.keysym.sym) {
-								case SDLK_LEFT:
-									if (wc) {
-										if (w % (cvstat.scrnwidth)) {
-											w = w - w % cvstat.scrnwidth;
-										}
-										else {
-											w -= cvstat.scrnwidth;
-											if (w < cvstat.scrnwidth)
-												w = cvstat.scrnwidth;
-										}
-									}
-									else {
-										if (h % (cvstat.scrnheight)) {
-											h = h - h % cvstat.scrnheight;
-										}
-										else {
-											h -= cvstat.scrnheight;
-											if (h < cvstat.scrnheight)
-												h = cvstat.scrnheight;
-										}
-									}
-									break;
-								case SDLK_RIGHT:
-									if (wc)
-										w = (w - w % cvstat.scrnwidth) + cvstat.scrnwidth;
-									else
-										h = (h - h % cvstat.scrnheight) + cvstat.scrnheight;
-									break;
+							int w, h;
+							SDL_Rect r;
+							if (sdl.GetDisplayUsableBounds(0, &r) == 0) {
+								w = r.w;
+								h = r.h;
 							}
-							if (wc)
-								h = INT_MAX;
-							else
-								w = INT_MAX;
-							aspect_fix(&w, &h, cvstat.aspect_width, cvstat.aspect_height);
-							if (w > 16384 || h > 16384)
-								beep();
 							else {
-								cvstat.winwidth = w;
-								cvstat.winheight = h;
-								internal_scaling = window_can_scale_internally(&cvstat);
+								w = 0;
+								h = 0;
 							}
+							pthread_mutex_lock(&vstatlock);
+							bitmap_snap(ev.key.keysym.sym == SDLK_RIGHT, w, h);
+							pthread_mutex_unlock(&vstatlock);
+							update_cvstat(&cvstat);
 							setup_surfaces_locked(&cvstat);
 						}
 						break;
diff --git a/src/conio/sdlfuncs.c b/src/conio/sdlfuncs.c
index 00e30bfbcde77b6f352720103ba13807a88d5986..4df3beab8c8f61f35df74b2f6116bea1fe1235ef 100644
--- a/src/conio/sdlfuncs.c
+++ b/src/conio/sdlfuncs.c
@@ -202,6 +202,10 @@ int load_sdl_funcs(struct sdlfuncs *sdlf)
 		xp_dlclose(sdl_dll);
 		return(-1);
 	}
+	if((sdlf->GetDisplayUsableBounds=xp_dlsym(sdl_dll, SDL_GetDisplayUsableBounds))==NULL) {
+		xp_dlclose(sdl_dll);
+		return(-1);
+	}
 #ifndef STATIC_SDL
 	{
 		int (HACK_HACK_HACK *ra)(char *name, Uint32 style, void *hInst);
diff --git a/src/conio/sdlfuncs.h b/src/conio/sdlfuncs.h
index 7dd75bdf9bea504c97fc40e614fd1abd9d55745b..bf52c2b7f705e5811be9197041e478b10e688ae7 100644
--- a/src/conio/sdlfuncs.h
+++ b/src/conio/sdlfuncs.h
@@ -56,6 +56,7 @@ struct sdlfuncs {
 	void (HACK_HACK_HACK *FreeCursor)	(SDL_Cursor *curs);
 	void(HACK_HACK_HACK *free)	(void *);
 	Uint32(HACK_HACK_HACK *GetWindowFlags)	(SDL_Window * window);
+	int (HACK_HACK_HACK *GetDisplayUsableBounds) (int, SDL_Rect *);
 	int	gotfuncs;
 };
 
diff --git a/src/conio/win32gdi.c b/src/conio/win32gdi.c
index 001e12d1ffc515a940e61fc796cedd77cc5af203..e6a166faeda0f2bad27b52181e4fdb4e59499697 100644
--- a/src/conio/win32gdi.c
+++ b/src/conio/win32gdi.c
@@ -197,8 +197,8 @@ UnadjustWindowSize(int *w, int *h)
 
 	ret = AdjustWindowRect(&r, style, FALSE);
 	if (ret) {
-		w += r.left - r.right;
-		h += r.top - r.bottom;
+		*w += r.left - r.right;
+		*h += r.top - r.bottom;
 	}
 	return ret;
 }
@@ -222,7 +222,6 @@ gdi_handle_wm_size(WPARAM wParam, LPARAM lParam)
 		return 0;
 	w = lParam & 0xffff;
 	h = (lParam >> 16) & 0xffff;
-	UnadjustWindowSize(&w, &h);
 	pthread_mutex_lock(&vstatlock);
 	vstat.winwidth = w;
 	vstat.winheight = h;
@@ -519,76 +518,34 @@ gdi_WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
 	return DefWindowProcW(hwnd, msg, wParam, lParam);
 }
 
+static bool
+gdi_get_monitor_size(int *w, int *h)
+{
+	HMONITOR mon;
+	MONITORINFO mi;
+	bool ret;
+
+	mon = MonitorFromWindow(win, MONITOR_DEFAULTTOPRIMARY);
+	mi.cbSize = sizeof(mi);
+	ret = GetMonitorInfoW(mon, &mi);
+	*w = mi.rcWork.right - mi.rcWork.left;
+	*h = mi.rcWork.bottom - mi.rcWork.top;
+	return ret;
+}
+
 static void
 gdi_snap(bool grow)
 {
-	bool wc;
-	int w, h;
 	int mw, mh;
 
 	if (maximized)
 		return;
-	mw = GetSystemMetrics(SM_CXMAXTRACK);
-	mh = GetSystemMetrics(SM_CYMAXTRACK);
+	gdi_get_monitor_size(&mw, &mh);
 	UnadjustWindowSize(&mw, &mh);
 	pthread_mutex_lock(&vstatlock);
-	w = vstat.winwidth;
-	h = vstat.winheight;
-	aspect_fix_inside(&w, &h, vstat.aspect_width, vstat.aspect_height);
-	if (vstat.aspect_width == 0 || vstat.aspect_height == 0)
-		wc = true;
-	else
-		wc = lround((double)(h * vstat.aspect_width) / vstat.aspect_height * vstat.scrnwidth / vstat.scrnheight) > w;
-	if (wc)
-		mw = mw - mw % vstat.scrnwidth;
-	else
-		mh = mh - mh % vstat.scrnheight;
-	mh = mw - mw % vstat.scrnwidth;
-	if (grow) {
-		if (wc)
-			w = (w - w % vstat.scrnwidth) + vstat.scrnwidth;
-		else
-			h = (h - h % vstat.scrnheight) + vstat.scrnheight;
-	}
-	else {
-		if (wc) {
-			if (w % (vstat.scrnwidth)) {
-				w = w - w % vstat.scrnwidth;
-			}
-			else {
-				w -= vstat.scrnwidth;
-				if (w < vstat.scrnwidth)
-					w = vstat.scrnwidth;
-			}
-		}
-		else {
-			if (h % (vstat.scrnheight)) {
-				h = h - h % vstat.scrnheight;
-			}
-			else {
-				h -= vstat.scrnheight;
-				if (h < vstat.scrnheight)
-					h = vstat.scrnheight;
-			}
-		}
-	}
-	if (wc)
-		h = INT_MAX;
-	else
-		w = INT_MAX;
-	if (w > mw)
-		w = mw;
-	if (h > mh)
-		h = mh;
-	aspect_fix_inside(&w, &h, vstat.aspect_width, vstat.aspect_height);
-	if (w > 16384 || h > 16384)
-		gdi_beep();
-	else {
-		vstat.winwidth = w;
-		vstat.winheight = h;
-		set_ciolib_scaling();
-		gdi_setwinsize(w, h);
-	}
+	bitmap_snap(grow, mw, mh);
+	set_ciolib_scaling();
+	gdi_setwinsize(vstat.winwidth, vstat.winheight);
 	pthread_mutex_unlock(&vstatlock);
 }
 
@@ -618,7 +575,6 @@ magic_message(MSG msg)
 			r.left = r.top = 0;
 			r.right = vstat.winwidth = msg.wParam;
 			r.bottom = vstat.winheight = msg.lParam;
-			set_ciolib_scaling();
 			pthread_mutex_unlock(&vstatlock);
 			AdjustWindowRect(&r, style, FALSE);
 			SetWindowPos(win, NULL, 0, 0, r.right - r.left, r.bottom - r.top, SWP_NOMOVE|SWP_NOOWNERZORDER|SWP_NOZORDER);
@@ -778,8 +734,8 @@ gdi_beep(void)
 void
 gdi_textmode(int mode)
 {
-	int oldcols;
 	int scaling = 1;
+	int mw, mh;
 
 	if (mode != CIOLIB_MODE_CUSTOM) {
 		pthread_mutex_lock(&vstatlock);
@@ -791,37 +747,9 @@ gdi_textmode(int mode)
 	}
 
 	pthread_mutex_lock(&vstatlock);
-	oldcols = vstat.cols;
-	bitmap_drv_init_mode(mode, NULL, NULL);
-	if (vstat.scrnwidth > 0) {
-		for (scaling = 1; (scaling + 1) * vstat.scrnwidth < vstat.winwidth; scaling++)
-			;
-	}
-	vstat.winwidth = vstat.scrnwidth * scaling;
-	vstat.winheight = vstat.scrnheight * scaling;
-	aspect_fix_inside(&vstat.winwidth, &vstat.winheight, vstat.aspect_width, vstat.aspect_height);
-	if (oldcols != vstat.cols) {
-		if (oldcols == 0) {
-			if (ciolib_initial_window_width > 0)
-				vstat.winwidth = ciolib_initial_window_width;
-			if (ciolib_initial_window_height > 0)
-				vstat.winheight = ciolib_initial_window_height;
-			if (vstat.cols == 40)
-				oldcols = 40;
-		}
-		if (oldcols == 40) {
-			vstat.winwidth /= 2;
-			vstat.winheight /= 2;
-		}
-		if (vstat.cols == 40) {
-			vstat.winwidth *= 2;
-			vstat.winheight *= 2;
-		}
-	}
-	if (vstat.winwidth < vstat.scrnwidth)
-		vstat.winwidth = vstat.scrnwidth;
-	if (vstat.winheight < vstat.scrnheight)
-		vstat.winheight = vstat.scrnheight;
+	gdi_get_monitor_size(&mw, &mh);
+	UnadjustWindowSize(&mw, &mh);
+	bitmap_drv_init_mode(mode, NULL, NULL, mw, mh);
 	set_ciolib_scaling();
 	gdi_setwinsize(vstat.winwidth, vstat.winheight);
 	pthread_mutex_unlock(&vstatlock);
diff --git a/src/conio/x_events.c b/src/conio/x_events.c
index ee5704f40628b8a9eb947e62c704f3ac20d201bc..a7de3d588b2196b82bb9e19a0b029120272bc70a 100644
--- a/src/conio/x_events.c
+++ b/src/conio/x_events.c
@@ -417,7 +417,7 @@ static void init_mode_internal(int mode)
 		release_buffer(last);
 		last = NULL;
 	}
-	bitmap_drv_init_mode(mode, &bitmap_width, &bitmap_height);
+	bitmap_drv_init_mode(mode, &bitmap_width, &bitmap_height, 0, 0);
 
 	/* Deal with 40 col doubling */
 	if(oldcols != vstat.cols) {