Fix graphics flickering/stretching on Windows (#367)

* DRY, standardized window top offset
* handle_splash_events() handle multiple events per frame
* accurate windows menubar height for multiple rows
* Windows filter a resize event triggered by the menubar
* windows expand small window to fit menubar
* splash screens draw in view rect, not window rect
This commit is contained in:
2024-06-27 06:40:34 -06:00
committed by GitHub
parent d6ae801203
commit c251fee834
12 changed files with 109 additions and 76 deletions

View File

@@ -144,16 +144,9 @@ static void init_scrollbars() {
sf::FloatRect compute_viewport(const sf::RenderWindow & mainPtr, float ui_scale) {
// See compute_viewport() in boe.graphics.cpp
const int os_specific_y_offset =
#if defined(SFML_SYSTEM_WINDOWS) || defined(SFML_SYSTEM_MAC)
0;
#else
getMenubarHeight();
#endif
sf::FloatRect viewport;
viewport.top = float(os_specific_y_offset) / mainPtr.getSize().y;
viewport.top = float(os_specific_y_offset()) / mainPtr.getSize().y;
viewport.left = 0;
viewport.width = ui_scale;
viewport.height = ui_scale;
@@ -169,11 +162,7 @@ void adjust_windows (sf::RenderWindow & mainPtr, sf::View & mainView) {
double ui_scale = get_float_pref("UIScale", 1.0);
const int width = ui_scale * 584;
const int height = ui_scale * 420
#ifndef SFML_SYSTEM_WINDOWS
+ getMenubarHeight()
#endif
;
const int height = ui_scale * 420 + os_specific_y_offset();
mainPtr.create(sf::VideoMode(width, height), "Blades of Exile Scenario Editor", sf::Style::Titlebar | sf::Style::Close);
sf::VideoMode desktop = sf::VideoMode::getDesktopMode();
@@ -195,6 +184,7 @@ void adjust_windows (sf::RenderWindow & mainPtr, sf::View & mainView) {
mainPtr.setIcon(icon->getSize().x, icon->getSize().y, icon->copyToImage().getPixelsPtr());
#endif
init_menubar();
adjust_window_for_menubar(5, width, height);
}
void process_args(int argc, char* argv[]) {

View File

@@ -58,16 +58,10 @@ void init_menubar() {
if(winHandle == NULL) return;
if(menuHandle == NULL)
menuHandle = LoadMenu(GetModuleHandle(NULL), MAKEINTRESOURCE(IDR_MENU1));
SetMenu(winHandle, menuHandle);
// Now we have to do a little hack to handle menu messages.
// We replace SFML's window procedure with our own, which checks for menu events and then forwards to SFML's procedure.
mainProc = SetWindowLongPtr(winHandle, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(&menuProc));
// Fix the window's viewport so that everything is drawn correctly
sf::Vector2u sz = mainPtr.getSize();
double menubarHeight = getMenubarHeight();
double usableHeight = sz.y - menubarHeight;
sf::View view(sf::FloatRect(0, 0, sz.x, usableHeight));
mainPtr.setView(view);
SetMenu(winHandle, menuHandle);
// And now initialize the mapping from Windows menu commands to eMenu constants
static bool inited = false;
@@ -218,6 +212,16 @@ void update_edit_menu() {
LRESULT CALLBACK menuProc(HWND handle, UINT message, WPARAM wParam, LPARAM lParam) {
MSG msg = {handle, message, wParam, lParam};
// Adding the menubar to the window for the first time triggers an unwanted
// resizing of the window, which we skip processing because it skews our
// viewport:
static bool menubarTriggeredResize = false;
if(message == WM_SIZE && !menubarTriggeredResize) {
menubarTriggeredResize = true;
return true;
}
if(HIWORD(wParam) != 1 || message != WM_COMMAND) {
if(TranslateAccelerator(handle, accel.handle, &msg))
return 0;