Run more iterations and retested

Not fully sure this is much different from the previous solution, but proof of test working as expected.
This commit is contained in:
andresdelcampo
2025-08-30 12:05:41 +02:00
parent 717b66c660
commit ca429dd493
2 changed files with 56 additions and 49 deletions

View File

@@ -171,6 +171,8 @@ extern "C" void qt_blit(int x, int y, int w, int h, int monitor_index);
extern MainWindow *main_window;
bool MainWindow::s_adjustingForce43 = false;
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
@@ -1017,69 +1019,73 @@ void MainWindow::updateShortcuts()
}
void
MainWindow::adjustToForce43(int suggestedW, int suggestedH)
MainWindow::adjustForForce43(const QSize &newWinSize)
{
// Only in resizable window mode with Force 4:3, and not fullscreen
if (!(vid_resize == 1 && force_43 > 0) || video_fullscreen)
// Only act in resizable mode with Force 4:3 enabled and not fullscreen
if (!(vid_resize == 1 && force_43 > 0) || video_fullscreen || s_adjustingForce43)
return;
static bool inAdjust = false; // prevent recursion
if (inAdjust) return;
inAdjust = true;
s_adjustingForce43 = true;
// Make sure the render widget is allowed to stretch in resizable mode.
// (Normally this is done once via resizeContents, but that path is skipped in vid_resize==1.)
ui->stackedWidget->setFixedSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX);
// Height consumed by menu/status/toolbars
int chromeH = menuBar()->height()
+ (hide_status_bar ? 0 : statusBar()->height())
+ (hide_tool_bar ? 0 : ui->toolBar->height());
const int frameExtra =
menuBar()->height() +
(hide_status_bar ? 0 : statusBar()->height()) +
(hide_tool_bar ? 0 : ui->toolBar->height());
// Window size were trying to honor (may come from the QResizeEvent)
int winW = (suggestedW >= 0) ? suggestedW : width();
int winH = (suggestedH >= 0) ? suggestedH : height();
// Work in logical pixels consistent with the rest of the file
const double dpr = (!dpi_scale ? util::screenOfWidget(this)->devicePixelRatio() : 1.0);
// Compute client area size in deviceindependent pixels
double dpr = (!dpi_scale ? util::screenOfWidget(this)->devicePixelRatio() : 1.0);
int winW = newWinSize.width();
int winH = newWinSize.height();
int clientW = static_cast<int>(winW / dpr);
int clientH = static_cast<int>((winH - frameExtra) / dpr);
if (clientH < 1) clientH = 1; // safety
int clientH = static_cast<int>((winH - chromeH) / dpr);
// Fit a 4:3 box INSIDE the dragged rectangle
const int wForH = (clientH * 4) / 3;
const int hForW = (clientW * 3) / 4;
if (wForH <= clientW) clientW = wForH; else clientH = hForW;
if (clientW <= 0 || clientH <= 0) {
s_adjustingForce43 = false;
return;
}
// Convert back to window size (device pixels + chrome)
const int newWinW = static_cast<int>(clientW * dpr);
const int newWinH = static_cast<int>(clientH * dpr) + frameExtra;
// Decide which dimension the user changed most adjust the other
int curW = static_cast<int>(width() / dpr);
int curH = static_cast<int>((height() - chromeH) / dpr);
bool widthChanged = std::abs(clientW - curW) >= std::abs(clientH - curH);
if (newWinW != winW || newWinH != winH)
this->resize(newWinW, newWinH);
int targetW, targetH;
if (widthChanged) {
// user dragged width compute matching height for 4:3
targetW = clientW;
targetH = (clientW * 3) / 4;
} else {
// user dragged height compute matching width for 4:3
targetH = clientH;
targetW = (clientH * 4) / 3;
}
// Keep the emulators notion of the requested screen size in sync
monitors[0].mon_scrnsz_x = clientW;
monitors[0].mon_scrnsz_y = clientH;
// Convert back to window size including chrome and apply
int newW = static_cast<int>(targetW * dpr);
int newH = static_cast<int>(targetH * dpr) + chromeH;
if (newW != winW || newH != winH)
resize(newW, newH);
// Notify both paths used elsewhere
ui->stackedWidget->onResize(width(), height()); // re-compute scale in the renderer
plat_resize_request(clientW, clientH, /*monitor_index=*/0);
// Update emulator framebuffer size and notify platform
monitors[0].mon_scrnsz_x = targetW;
monitors[0].mon_scrnsz_y = targetH;
plat_resize_request(targetW, targetH, 0);
inAdjust = false;
// Allow renderer widget to grow and recompute scaling
ui->stackedWidget->setFixedSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX);
ui->stackedWidget->onResize(width(), height());
s_adjustingForce43 = false;
}
void
MainWindow::resizeEvent(QResizeEvent *event)
{
//qDebug() << pos().x() + event->size().width();
//qDebug() << pos().y() + event->size().height();
// Enforce 4:3 while dragging in resizable mode
if (vid_resize == 1 && force_43 > 0 && !video_fullscreen) {
adjustToForce43(event->size().width(), event->size().height());
return; // weve already applied the corrected size & notified core
}
// Enforce 4:3 aspect ratio in resizable mode when the option is set
adjustForForce43(event->size());
if (vid_resize == 1 || video_fullscreen)
return;
@@ -2136,14 +2142,13 @@ MainWindow::on_actionForce_4_3_display_ratio_triggered()
{
video_toggle_option(ui->actionForce_4_3_display_ratio, &force_43);
// When turning on Force 4:3 in resizable mode, immediately snap to 4:3
if (vid_resize == 1 && !video_fullscreen) {
// Ensure the render widget can stretch in resizable mode
ui->stackedWidget->setFixedSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX);
if (force_43 > 0) {
// Snap to 4:3 now
adjustToForce43(); // uses current window size
adjustForForce43(size());
} else {
// Turning OFF: reflow the renderer to current window size
// Turning off: refresh renderer scaling
ui->stackedWidget->onResize(width(), height());
}
}

View File

@@ -176,7 +176,9 @@ private:
std::unique_ptr<MachineStatus> status;
std::shared_ptr<MediaMenu> mm;
void adjustToForce43(int suggestedW = -1, int suggestedH = -1);
static bool s_adjustingForce43; // guard against recursion
void adjustForForce43(const QSize &newWinSize);
void updateShortcuts();
void processKeyboardInput(bool down, uint32_t keycode);
#ifdef Q_OS_MACOS