From fd79a9a99d1fa1b811b65db366692fee00904021 Mon Sep 17 00:00:00 2001 From: David 'Digit' Turner Date: Thu, 26 May 2011 15:50:43 +0200 Subject: Auto-adjust scale and window position when needed. This is a backport from master to tools_r13 This patch changes the emulator's default behaviour in two ways: - Automatically compute the window scale to ensure that the emulator's window can be displayed within the current screen. This ensures that it remains usable when emulating a large-resolution device on a small display (e.g. on a 13" laptop running at 1024x768). This check and auto-correction do not happen if you use the -scale or -dpi-monitor options. - When re-centering an out-of-focus window, ensure that the top of the window is visible (which generally includes the window's title bar). This allows the window to be easily moved or minimized by the user is needed. This fixes three bugs: http://code.google.com/p/android/issues/detail?id=16399 http://code.google.com/p/android/issues/detail?id=16398 http://code.google.com/p/android/issues/detail?id=16397 Change-Id: Ibbc3c8458bd99718e4902d0a032b154c7cff4757 Orig-Change-Id: I8e5a624446d064038b5b9ad16556db8328244906 --- android/qemulator.c | 3 --- android/skin/window.c | 61 +++++++++++++++++++++++++++++++++++++++++++++------ android/skin/window.h | 5 +++++ 3 files changed, 59 insertions(+), 10 deletions(-) diff --git a/android/qemulator.c b/android/qemulator.c index b15d751..d29ee94 100644 --- a/android/qemulator.c +++ b/android/qemulator.c @@ -330,9 +330,6 @@ get_default_scale( AndroidOptions* opts ) if (scale == 0.0 && dpi_monitor > 0) scale = dpi_monitor*1.0/dpi_device; - if (scale == 0.0) - scale = 1.0; - return scale; } diff --git a/android/skin/window.c b/android/skin/window.c index 2755763..c1bf23f 100644 --- a/android/skin/window.c +++ b/android/skin/window.c @@ -1134,6 +1134,36 @@ skin_window_create( SkinLayout* slayout, int x, int y, double scale, int no { SkinWindow* window; + /* If scale is <= 0, we want to check that the window's default size if + * not larger than the current screen. Otherwise, we need to compute + * a new scale to ensure it is. + */ + if (scale <= 0) { + SDL_Rect monitor; + int screen_w, screen_h; + int win_w = slayout->size.w; + int win_h = slayout->size.h; + double scale_w, scale_h; + + /* To account for things like menu bars, window decorations etc.. + * We only compute 95% of the real screen size. */ + SDL_WM_GetMonitorRect(&monitor); + screen_w = monitor.w * 0.95; + screen_h = monitor.h * 0.95; + + scale_w = 1.0; + scale_h = 1.0; + + if (screen_w < win_w && win_w > 1.) + scale_w = 1.0 * screen_w / win_w; + if (screen_h < win_h && win_h > 1.) + scale_h = 1.0 * screen_h / win_h; + + scale = (scale_w <= scale_h) ? scale_w : scale_h; + + VERBOSE_PRINT(init,"autoconfig: -scale %g", scale); + } + ANEW0(window); window->shrink_scale = scale; @@ -1151,14 +1181,33 @@ skin_window_create( SkinLayout* slayout, int x, int y, double scale, int no window->y_pos = y; if (skin_window_reset_internal(window, slayout) < 0) { - skin_window_free( window ); + skin_window_free(window); return NULL; } - //SDL_WM_SetCaption( "Android Emulator", "Android Emulator" ); - SDL_WM_SetPos( x, y ); - if ( !SDL_WM_IsFullyVisible( 1 ) ) { - dprint( "emulator window was out of view and was recentred\n" ); + + /* Check that the window is fully visible */ + if ( !window->no_display && !SDL_WM_IsFullyVisible(0) ) { + SDL_Rect monitor; + int win_x, win_y, win_w, win_h; + int new_x, new_y; + + SDL_WM_GetMonitorRect(&monitor); + SDL_WM_GetPos(&win_x, &win_y); + win_w = window->surface->w; + win_h = window->surface->h; + + /* First, we recenter the window */ + new_x = (monitor.w - win_w)/2; + new_y = (monitor.h - win_h)/2; + + /* If it is still too large, we ensure the top-border is visible */ + if (new_y < 0) + new_y = 0; + + /* Done */ + SDL_WM_SetPos(new_x, new_y); + dprint( "emulator window was out of view and was recentered\n" ); } return window; @@ -1316,8 +1365,6 @@ skin_window_reset_internal ( SkinWindow* window, SkinLayout* slayout ) if ( layout_init( &layout, slayout ) < 0 ) return -1; - disp = window->layout.displays; - layout_done( &window->layout ); window->layout = layout; diff --git a/android/skin/window.h b/android/skin/window.h index 3e92e40..5ba90f5 100644 --- a/android/skin/window.h +++ b/android/skin/window.h @@ -18,6 +18,11 @@ typedef struct SkinWindow SkinWindow; +/* Note: if scale is <= 0, we interpret this as 'auto-detect'. + * The behaviour is to use 1.0 by default, unless the resulting + * window is too large, in which case the window will automatically + * be resized to fit the screen. + */ extern SkinWindow* skin_window_create( SkinLayout* layout, int x, int y, -- cgit v1.1