Merge pull request #2598 from Cacodemon345/qt-fullscreen-stretch-maximize

qt: Add option to apply fullscreen stretching modes when maximized
This commit is contained in:
Miran Grča
2022-08-09 21:35:42 +02:00
committed by GitHub
16 changed files with 69 additions and 4 deletions

View File

@@ -188,6 +188,7 @@ int enable_discord = 0; /* (C) enable Discord integration */
int pit_mode = -1; /* (C) force setting PIT mode */ int pit_mode = -1; /* (C) force setting PIT mode */
int fm_driver = 0; /* (C) select FM sound driver */ int fm_driver = 0; /* (C) select FM sound driver */
int open_dir_usr_path = 0; /* default file open dialog directory of usr_path */ int open_dir_usr_path = 0; /* default file open dialog directory of usr_path */
int video_fullscreen_scale_maximized = 0; /* (C) Whether fullscreen scaling settings also apply when maximized. */
/* Statistics. */ /* Statistics. */
extern int mmuflush; extern int mmuflush;

View File

@@ -969,6 +969,8 @@ load_video(void)
ibm8514_enabled = !!config_get_int(cat, "8514a", 0); ibm8514_enabled = !!config_get_int(cat, "8514a", 0);
xga_enabled = !!config_get_int(cat, "xga", 0); xga_enabled = !!config_get_int(cat, "xga", 0);
show_second_monitors = !!config_get_int(cat, "show_second_monitors", 1); show_second_monitors = !!config_get_int(cat, "show_second_monitors", 1);
video_fullscreen_scale_maximized = !!config_get_int(cat, "video_fullscreen_scale_maximized", 0);
p = config_get_string(cat, "gfxcard_2", NULL); p = config_get_string(cat, "gfxcard_2", NULL);
if (!p) if (!p)
p = "none"; p = "none";
@@ -2554,6 +2556,11 @@ save_video(void)
else else
config_set_int(cat, "show_second_monitors", show_second_monitors); config_set_int(cat, "show_second_monitors", show_second_monitors);
if (video_fullscreen_scale_maximized == 0)
config_delete_var(cat, "video_fullscreen_scale_maximized");
else
config_set_int(cat, "video_fullscreen_scale_maximized", video_fullscreen_scale_maximized);
delete_section_if_empty(cat); delete_section_if_empty(cat);
} }

View File

@@ -133,6 +133,7 @@ extern atomic_bool doresize_monitors[MONITORS_NUM];
extern int monitor_index_global; extern int monitor_index_global;
extern int gfxcard_2; extern int gfxcard_2;
extern int show_second_monitors; extern int show_second_monitors;
extern int video_fullscreen_scale_maximized;
typedef rgb_t PALETTE[256]; typedef rgb_t PALETTE[256];

View File

@@ -145,6 +145,7 @@ void D3D9Renderer::blit(int x, int y, int w, int h)
return; return;
} }
surfaceInUse = true; surfaceInUse = true;
auto origSource = source;
source.setRect(x, y, w, h); source.setRect(x, y, w, h);
RECT srcRect; RECT srcRect;
D3DLOCKED_RECT lockRect; D3DLOCKED_RECT lockRect;
@@ -164,6 +165,7 @@ void D3D9Renderer::blit(int x, int y, int w, int h)
d3d9surface->UnlockRect(); d3d9surface->UnlockRect();
} }
else video_blit_complete_monitor(m_monitor_index); else video_blit_complete_monitor(m_monitor_index);
if (origSource != source) onResize(this->width() * devicePixelRatioF(), this->height() * devicePixelRatioF());
surfaceInUse = false; surfaceInUse = false;
QTimer::singleShot(0, this, [this] { this->update(); }); QTimer::singleShot(0, this, [this] { this->update(); });
} }

View File

@@ -134,6 +134,7 @@ void HardwareRenderer::initializeGL()
pclog("OpenGL version: %s\n", glGetString(GL_VERSION)); pclog("OpenGL version: %s\n", glGetString(GL_VERSION));
pclog("OpenGL shader language version: %s\n", glGetString(GL_SHADING_LANGUAGE_VERSION)); pclog("OpenGL shader language version: %s\n", glGetString(GL_SHADING_LANGUAGE_VERSION));
glClearColor(0, 0, 0, 1); glClearColor(0, 0, 0, 1);
m_texture->setWrapMode(QOpenGLTexture::ClampToEdge);
} }
void HardwareRenderer::paintGL() { void HardwareRenderer::paintGL() {
@@ -187,6 +188,7 @@ void HardwareRenderer::onBlit(int buf_idx, int x, int y, int w, int h) {
auto tval = this; auto tval = this;
void* nuldata = 0; void* nuldata = 0;
if (memcmp(&tval, &nuldata, sizeof(void*)) == 0) return; if (memcmp(&tval, &nuldata, sizeof(void*)) == 0) return;
auto origSource = source;
if (!m_texture || !m_texture->isCreated()) if (!m_texture || !m_texture->isCreated())
{ {
buf_usage[buf_idx].clear(); buf_usage[buf_idx].clear();
@@ -197,6 +199,7 @@ void HardwareRenderer::onBlit(int buf_idx, int x, int y, int w, int h) {
m_texture->setData(QOpenGLTexture::PixelFormat::RGBA, QOpenGLTexture::PixelType::UInt8, (const void*)imagebufs[buf_idx].get()); m_texture->setData(QOpenGLTexture::PixelFormat::RGBA, QOpenGLTexture::PixelType::UInt8, (const void*)imagebufs[buf_idx].get());
buf_usage[buf_idx].clear(); buf_usage[buf_idx].clear();
source.setRect(x, y, w, h); source.setRect(x, y, w, h);
if (origSource != source) onResize(this->width(), this->height());
update(); update();
} }

View File

@@ -47,6 +47,10 @@ public:
void resizeGL(int w, int h) override; void resizeGL(int w, int h) override;
void initializeGL() override; void initializeGL() override;
void paintGL() override; void paintGL() override;
void exposeEvent(QExposeEvent* event) override
{
onResize(size().width(), size().height());
}
std::vector<std::tuple<uint8_t*, std::atomic_flag*>> getBuffers() override; std::vector<std::tuple<uint8_t*, std::atomic_flag*>> getBuffers() override;
HardwareRenderer(QWidget* parent = nullptr, RenderType rtype = RenderType::OpenGL) HardwareRenderer(QWidget* parent = nullptr, RenderType rtype = RenderType::OpenGL)
: QOpenGLWindow(QOpenGLWindow::NoPartialUpdate, parent->windowHandle()), QOpenGLFunctions() : QOpenGLWindow(QOpenGLWindow::NoPartialUpdate, parent->windowHandle()), QOpenGLFunctions()

View File

@@ -133,6 +133,8 @@ std::atomic<bool> blitDummied{false};
extern void qt_mouse_capture(int); extern void qt_mouse_capture(int);
extern "C" void qt_blit(int x, int y, int w, int h, int monitor_index); extern "C" void qt_blit(int x, int y, int w, int h, int monitor_index);
extern MainWindow* main_window;
MainWindow::MainWindow(QWidget *parent) : MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent), QMainWindow(parent),
ui(new Ui::MainWindow) ui(new Ui::MainWindow)
@@ -293,6 +295,7 @@ MainWindow::MainWindow(QWidget *parent) :
ui->actionShow_non_primary_monitors->setChecked(show_second_monitors); ui->actionShow_non_primary_monitors->setChecked(show_second_monitors);
ui->actionUpdate_status_bar_icons->setChecked(update_icons); ui->actionUpdate_status_bar_icons->setChecked(update_icons);
ui->actionEnable_Discord_integration->setChecked(enable_discord); ui->actionEnable_Discord_integration->setChecked(enable_discord);
ui->actionApply_fullscreen_stretch_mode_when_maximized->setChecked(video_fullscreen_scale_maximized);
#if defined Q_OS_WINDOWS || defined Q_OS_MACOS #if defined Q_OS_WINDOWS || defined Q_OS_MACOS
/* Make the option visible only if ANGLE is loaded. */ /* Make the option visible only if ANGLE is loaded. */
@@ -1773,11 +1776,15 @@ static void update_fullscreen_scale_checkboxes(Ui::MainWindow* ui, QAction* sele
ui->actionFullScreen_keepRatio->setChecked(ui->actionFullScreen_keepRatio == selected); ui->actionFullScreen_keepRatio->setChecked(ui->actionFullScreen_keepRatio == selected);
ui->actionFullScreen_int->setChecked(ui->actionFullScreen_int == selected); ui->actionFullScreen_int->setChecked(ui->actionFullScreen_int == selected);
if (video_fullscreen > 0) { {
auto widget = ui->stackedWidget->currentWidget(); auto widget = ui->stackedWidget->currentWidget();
ui->stackedWidget->onResize(widget->width(), widget->height()); ui->stackedWidget->onResize(widget->width(), widget->height());
} }
for (int i = 1; i < MONITORS_NUM; i++) {
if (main_window->renderers[i]) main_window->renderers[i]->onResize(main_window->renderers[i]->width(), main_window->renderers[i]->height());
}
device_force_redraw(); device_force_redraw();
config_save(); config_save();
} }
@@ -2130,3 +2137,19 @@ void MainWindow::on_actionOpen_screenshots_folder_triggered()
QDesktopServices::openUrl(QUrl(QString("file:///") + usr_path + QString("/screenshots/"))); QDesktopServices::openUrl(QUrl(QString("file:///") + usr_path + QString("/screenshots/")));
} }
void MainWindow::on_actionApply_fullscreen_stretch_mode_when_maximized_triggered(bool checked)
{
video_fullscreen_scale_maximized = checked;
auto widget = ui->stackedWidget->currentWidget();
ui->stackedWidget->onResize(widget->width(), widget->height());
for (int i = 1; i < MONITORS_NUM; i++) {
if (renderers[i]) renderers[i]->onResize(renderers[i]->width(), renderers[i]->height());
}
device_force_redraw();
config_save();
}

View File

@@ -33,6 +33,8 @@ public:
void blitToWidget(int x, int y, int w, int h, int monitor_index); void blitToWidget(int x, int y, int w, int h, int monitor_index);
QSize getRenderWidgetSize(); QSize getRenderWidgetSize();
void setSendKeyboardInput(bool enabled); void setSendKeyboardInput(bool enabled);
std::array<std::unique_ptr<RendererStack>, 8> renderers;
signals: signals:
void paint(const QImage& image); void paint(const QImage& image);
void resizeContents(int w, int h); void resizeContents(int w, int h);
@@ -131,10 +133,11 @@ private slots:
void on_actionOpen_screenshots_folder_triggered(); void on_actionOpen_screenshots_folder_triggered();
void on_actionApply_fullscreen_stretch_mode_when_maximized_triggered(bool checked);
private: private:
Ui::MainWindow *ui; Ui::MainWindow *ui;
std::unique_ptr<MachineStatus> status; std::unique_ptr<MachineStatus> status;
std::array<std::unique_ptr<RendererStack>, 8> renderers;
std::shared_ptr<MediaMenu> mm; std::shared_ptr<MediaMenu> mm;
#ifdef Q_OS_MACOS #ifdef Q_OS_MACOS

View File

@@ -179,6 +179,7 @@
<addaction name="separator"/> <addaction name="separator"/>
<addaction name="actionFullscreen"/> <addaction name="actionFullscreen"/>
<addaction name="menuFullscreen_stretch_mode"/> <addaction name="menuFullscreen_stretch_mode"/>
<addaction name="actionApply_fullscreen_stretch_mode_when_maximized"/>
<addaction name="menuEGA_S_VGA_settings"/> <addaction name="menuEGA_S_VGA_settings"/>
<addaction name="separator"/> <addaction name="separator"/>
<addaction name="actionCGA_PCjr_Tandy_EGA_S_VGA_overscan"/> <addaction name="actionCGA_PCjr_Tandy_EGA_S_VGA_overscan"/>
@@ -785,6 +786,14 @@
<string>Open screenshots folder...</string> <string>Open screenshots folder...</string>
</property> </property>
</action> </action>
<action name="actionApply_fullscreen_stretch_mode_when_maximized">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>Apply fullscreen stretch mode when maximized</string>
</property>
</action>
</widget> </widget>
<customwidgets> <customwidgets>
<customwidget> <customwidget>

View File

@@ -80,6 +80,8 @@ OpenGLRenderer::exposeEvent(QExposeEvent *event)
if (!isInitialized) if (!isInitialized)
initialize(); initialize();
onResize(size().width(), size().height());
} }
void void

View File

@@ -47,7 +47,7 @@ static void integer_scale(double *d, double *g) {
} }
void RendererCommon::onResize(int width, int height) { void RendererCommon::onResize(int width, int height) {
if (video_fullscreen == 0) { if (video_fullscreen == 0 && video_fullscreen_scale_maximized ? (parentWidget->isMaximized() == false && (main_window->isAncestorOf(parentWidget) && main_window->isMaximized() == false)) : 1) {
destination.setRect(0, 0, width, height); destination.setRect(0, 0, width, height);
return; return;
} }

View File

@@ -37,7 +37,7 @@ public:
protected: protected:
bool eventDelegate(QEvent *event, bool &result); bool eventDelegate(QEvent *event, bool &result);
QRect source, destination; QRect source{0, 0, 0, 0}, destination;
QWidget *parentWidget { nullptr }; QWidget *parentWidget { nullptr };
std::vector<std::atomic_flag> buf_usage; std::vector<std::atomic_flag> buf_usage;

View File

@@ -397,6 +397,7 @@ RendererStack::createRenderer(Renderer renderer)
if (current.get() == nullptr) return; if (current.get() == nullptr) return;
current->setFocusPolicy(Qt::NoFocus); current->setFocusPolicy(Qt::NoFocus);
current->setFocusProxy(this); current->setFocusProxy(this);
current->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
addWidget(current.get()); addWidget(current.get());
this->setStyleSheet("background-color: black"); this->setStyleSheet("background-color: black");

View File

@@ -32,6 +32,10 @@ public:
void wheelEvent(QWheelEvent *event) override; void wheelEvent(QWheelEvent *event) override;
void leaveEvent(QEvent *event) override; void leaveEvent(QEvent *event) override;
void closeEvent(QCloseEvent *event) override; void closeEvent(QCloseEvent *event) override;
void resizeEvent(QResizeEvent *event) override
{
onResize(event->size().width(), event->size().height());
}
void keyPressEvent(QKeyEvent *event) override void keyPressEvent(QKeyEvent *event) override
{ {
event->ignore(); event->ignore();

View File

@@ -57,11 +57,14 @@ void SoftwareRenderer::onBlit(int buf_idx, int x, int y, int w, int h) {
auto tval = this; auto tval = this;
void* nuldata = 0; void* nuldata = 0;
if (memcmp(&tval, &nuldata, sizeof(void*)) == 0) return; if (memcmp(&tval, &nuldata, sizeof(void*)) == 0) return;
auto origSource = source;
cur_image = buf_idx; cur_image = buf_idx;
buf_usage[(buf_idx + 1) % 2].clear(); buf_usage[(buf_idx + 1) % 2].clear();
source.setRect(x, y, w, h); source.setRect(x, y, w, h);
if (source != origSource) onResize(this->width(), this->height());
update(); update();
} }

View File

@@ -836,9 +836,11 @@ bool VulkanWindowRenderer::event(QEvent *event)
void VulkanWindowRenderer::onBlit(int buf_idx, int x, int y, int w, int h) void VulkanWindowRenderer::onBlit(int buf_idx, int x, int y, int w, int h)
{ {
auto origSource = source;
source.setRect(x, y, w, h); source.setRect(x, y, w, h);
if (isExposed()) requestUpdate(); if (isExposed()) requestUpdate();
buf_usage[0].clear(); buf_usage[0].clear();
if (origSource != source) onResize(this->width(), this->height());
} }
uint32_t VulkanWindowRenderer::getBytesPerRow() uint32_t VulkanWindowRenderer::getBytesPerRow()