mirror of
https://github.com/libretro/RetroArch.git
synced 2026-11-08 08:10:30 -10:00
win32: an in-place fullscreen toggle tells the driver the window's real size
Going from fullscreen to windowed with a hardware-rendered core running (LRPS2 at 2560x1792), the picture sat in the top two thirds of the window with black below it. The statistics said the frontend was drawing for 3186x1240; the window's client area was 3186x1792. win32_window_set_fullscreen() restyles the window through the steps a new window goes through, and those leave g_win32_resize_width/height holding sizes worked out on the way - the window's outer size, then, with the menu bar on, an outer height with the menu added - counting on the WM_SIZE of the SetWindowPos that follows to put the client's size there. That message only comes when the size changes. A window is not allowed to be smaller than the core's picture (WM_GETMINMAXINFO), so with a core bigger than the window asked for - 1920x1080 asked, 3186x1792 the least allowed - the window is already at its minimum when the menu bar step resizes it, nothing changes, no message comes, and the worked-out height is what the video driver is told. The toggle now ends by reading the client area and reporting that. A window made by a driver restart goes through the same steps but is not affected, since the driver then takes its size from the swapchain it has just made; that path is left as it is. One GetClientRect per toggle; nothing on the frame path. samples/gfx/win32_window_proc has the case: a core bigger than the window asked for, menu bar on, toggled to fullscreen and back. Without the change the window grows as it should and the size reported is not the window's; with it, it is. The test's stand-in menu gets an item, so that it is a menu bar with a height.
This commit is contained in:
1 parent
f7302df6cb
commit
f2be48bfb8
5 files changed
+80
-1
No files matched your search
@@ -2234,6 +2234,32 @@ bool win32_window_set_fullscreen(unsigned dims, bool fullscreen)
|
||||
|
||||
win32_set_window(&width, &height, fullscreen, true, &rect);
|
||||
|
||||
/* What the video driver is told is the size the window has now.
|
||||
*
|
||||
* The steps above leave g_win32_resize_width/height holding sizes
|
||||
* worked out on the way - a window's outer size, then one with the
|
||||
* menu bar added - and count on the WM_SIZE of the SetWindowPos
|
||||
* that follows to put the client's size there. That message only
|
||||
* comes if the size changes. A window cannot be smaller than the
|
||||
* core's picture (WM_GETMINMAXINFO), so with a core bigger than the
|
||||
* window asked for the window is already at its minimum, the
|
||||
* second SetWindowPos changes nothing, and the worked-out height
|
||||
* stayed: the driver drew for a window shorter than the one on
|
||||
* screen, and the picture sat in the top of it. A window made by a
|
||||
* driver restart is not affected, because that driver takes its
|
||||
* size from the swapchain it has just made. */
|
||||
{
|
||||
RECT client;
|
||||
if ( GetClientRect(hwnd, &client)
|
||||
&& client.right > client.left
|
||||
&& client.bottom > client.top)
|
||||
{
|
||||
g_win32_resize_width = client.right - client.left;
|
||||
g_win32_resize_height = client.bottom - client.top;
|
||||
g_win32_flags |= WIN32_CMN_FLAG_RESIZED;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -2695,5 +2695,6 @@
|
||||
window objects left behind: no
|
||||
== 20 fullscreen toggles on one window
|
||||
same window 20, right style 20, right size 20, resize seen 20
|
||||
a window grown to fit a bigger core: grew yes, driver told its real size yes
|
||||
exclusive fullscreen left to a restart: yes
|
||||
destroyed: window gone
|
||||
@@ -188,6 +188,14 @@ static ui_application_t stub_application;
|
||||
const ui_window_t *ui_companion_driver_get_window_ptr(void) { return &stub_window; }
|
||||
ui_companion_driver_t ui_companion_win32;
|
||||
|
||||
/* the core's picture: the window code will not let its window be
|
||||
* smaller */
|
||||
void stub_set_geometry(unsigned width, unsigned height)
|
||||
{
|
||||
stub_video_st.av_info.geometry.base_width = width;
|
||||
stub_video_st.av_info.geometry.base_height = height;
|
||||
}
|
||||
|
||||
void stubs_init(void)
|
||||
{
|
||||
/* a core's geometry: the window limits its size to twenty times
|
||||
@@ -207,7 +215,12 @@ LRESULT win32_menu_loop(HWND owner, WPARAM wparam)
|
||||
return 0;
|
||||
}
|
||||
void win32_localize_menu(HMENU menu) { }
|
||||
HMENU win32_resources_create_menu(void) { return CreateMenu(); }
|
||||
HMENU win32_resources_create_menu(void)
|
||||
{
|
||||
HMENU menu = CreateMenu();
|
||||
AppendMenuA(menu, MF_STRING, 1, "File");
|
||||
return menu;
|
||||
}
|
||||
unsigned short win32_get_langid_from_retro_lang(enum retro_language lang) { return 0x0409; }
|
||||
|
||||
bool task_push_load_new_core(const char *core_path, const char *fullpath,
|
||||
|
||||
@@ -303,6 +303,8 @@ int main(int argc, char **argv)
|
||||
int cycle, same = 0, styled = 0, sized = 0, resized = 0;
|
||||
const int cycles = 20;
|
||||
bool refused;
|
||||
bool big_grew = false;
|
||||
bool big_told = false;
|
||||
|
||||
strlcpy(settings->arrays.input_driver, "raw",
|
||||
sizeof(settings->arrays.input_driver));
|
||||
@@ -350,6 +352,40 @@ int main(int argc, char **argv)
|
||||
resized++;
|
||||
}
|
||||
|
||||
/* A core whose picture is bigger than the window asked for,
|
||||
* with the menu bar on. The window code does not let a window
|
||||
* be smaller than the core's picture, so the window that
|
||||
* comes out of the toggle is bigger than the one asked for -
|
||||
* and the size the video driver is then told has to be the
|
||||
* size the window has, not one worked out on the way. */
|
||||
{
|
||||
RECT client;
|
||||
bool quit = false;
|
||||
bool resize = false;
|
||||
unsigned told_dims = 0;
|
||||
|
||||
settings->bools.ui_menubar_enable = true;
|
||||
stub_set_geometry(900, 600);
|
||||
|
||||
settings->bools.video_fullscreen = true;
|
||||
win32_window_set_fullscreen(VIDEO_SCALE_PACK(640, 480), true);
|
||||
pump();
|
||||
win32_window_reset();
|
||||
settings->bools.video_fullscreen = false;
|
||||
win32_window_set_fullscreen(VIDEO_SCALE_PACK(640, 480), false);
|
||||
pump();
|
||||
|
||||
win32_check_window(NULL, &quit, &resize, &told_dims);
|
||||
GetClientRect(hwnd, &client);
|
||||
big_grew = (client.right >= 900 && client.bottom >= 600);
|
||||
big_told = resize
|
||||
&& (LONG)VIDEO_SCALE_W(told_dims) == client.right
|
||||
&& (LONG)VIDEO_SCALE_H(told_dims) == client.bottom;
|
||||
|
||||
settings->bools.ui_menubar_enable = false;
|
||||
stub_set_geometry(320, 240);
|
||||
}
|
||||
|
||||
/* exclusive fullscreen changes the display mode: not done in
|
||||
* place, left to the driver restart */
|
||||
settings->bools.video_windowed_fullscreen = false;
|
||||
@@ -364,6 +400,8 @@ int main(int argc, char **argv)
|
||||
trace("== %d fullscreen toggles on one window\n", cycles);
|
||||
trace(" same window %d, right style %d, right size %d, resize seen %d\n",
|
||||
same, styled, sized, resized);
|
||||
trace(" a window grown to fit a bigger core: grew %s, driver told its real size %s\n",
|
||||
big_grew ? "yes" : "no", big_told ? "yes" : "no");
|
||||
trace(" exclusive fullscreen left to a restart: %s\n",
|
||||
refused ? "yes" : "no");
|
||||
trace(" destroyed: window %s\n", IsWindow(hwnd) ? "still there" : "gone");
|
||||
|
||||
@@ -12,4 +12,5 @@ extern bool trace_on;
|
||||
extern unsigned stub_create_steps;
|
||||
void trace(const char *fmt, ...);
|
||||
void stubs_init(void);
|
||||
void stub_set_geometry(unsigned width, unsigned height);
|
||||
#endif
|
||||
Reference in new issue
Block a user