From c577aa85f2966f03e5c63678c312d4d83d17261c Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Wed, 16 Feb 2022 01:09:11 +0600 Subject: [PATCH 1/6] qt: Add fullscreen status icons support and option --- src/config.c | 6 +++++ src/include/86box/plat.h | 5 ++-- src/qt/qt_hardwarerenderer.cpp | 22 ++++++++++++++-- src/qt/qt_hardwarerenderer.hpp | 1 + src/qt/qt_mainwindow.cpp | 14 ++++++++--- src/qt/qt_mainwindow.hpp | 4 ++- src/qt/qt_mainwindow.ui | 9 +++++++ src/qt/qt_renderercommon.cpp | 46 ++++++++++++++++++++++++++++++++++ src/qt/qt_renderercommon.hpp | 1 + src/qt/qt_softwarerenderer.cpp | 4 ++- src/unix/unix.c | 3 ++- src/win/win_ui.c | 1 + 12 files changed, 106 insertions(+), 10 deletions(-) diff --git a/src/config.c b/src/config.c index 5f3503ea9..b110d6984 100644 --- a/src/config.c +++ b/src/config.c @@ -521,6 +521,7 @@ load_general(void) rctrl_is_lalt = config_get_int(cat, "rctrl_is_lalt", 0); update_icons = config_get_int(cat, "update_icons", 1); + status_icons_fullscreen = !!config_get_int(cat, "status_icons_fullscreen", 0); window_remember = config_get_int(cat, "window_remember", 0); if (window_remember || (vid_resize & 2)) { @@ -2294,6 +2295,11 @@ save_general(void) else config_delete_var(cat, "enable_discord"); + if (status_icons_fullscreen) + config_set_int(cat, "status_icons_fullscreen", status_icons_fullscreen); + else + config_delete_var(cat, "status_icons_fullscreen"); + if (video_framerate != -1) config_set_int(cat, "video_gl_framerate", video_framerate); else diff --git a/src/include/86box/plat.h b/src/include/86box/plat.h index c60e6d922..d00bc1b87 100644 --- a/src/include/86box/plat.h +++ b/src/include/86box/plat.h @@ -75,7 +75,7 @@ extern "C" { /* Global variables residing in the platform module. */ extern int dopause, /* system is paused */ - mouse_capture; /* mouse is captured in app */ + mouse_capture; /* mouse is captured in app */ extern atomic_flag_t doresize; /* screen resize requested */ extern volatile int is_quit; /* system exit requested */ @@ -88,9 +88,10 @@ extern int infocus; extern char emu_version[200]; /* version ID string */ extern int rctrl_is_lalt; extern int update_icons; +extern int status_icons_fullscreen; extern int unscaled_size_x, /* current unscaled size X */ - unscaled_size_y; /* current unscaled size Y */ + unscaled_size_y; /* current unscaled size Y */ extern int kbd_req_capture, hide_status_bar, hide_tool_bar; diff --git a/src/qt/qt_hardwarerenderer.cpp b/src/qt/qt_hardwarerenderer.cpp index 1a89b93be..e4d2b4900 100644 --- a/src/qt/qt_hardwarerenderer.cpp +++ b/src/qt/qt_hardwarerenderer.cpp @@ -86,6 +86,7 @@ void HardwareRenderer::initializeGL() "void main(void)\n" "{\n" " gl_FragColor = texture2D(texture, texc.st).bgra;\n" + " gl_FragColor.a = 1.0;\n" "}\n"; QString fsrccore = "uniform sampler2D texture;\n" @@ -94,6 +95,7 @@ void HardwareRenderer::initializeGL() "void main(void)\n" "{\n" " FragColor = texture2D(texture, texc.st).bgra;\n" + " FragColor.a = 1.0;\n" "}\n"; if (m_context->isOpenGLES() && m_context->format().version() >= qMakePair(3, 0)) { @@ -135,6 +137,22 @@ void HardwareRenderer::initializeGL() glClearColor(0, 0, 0, 1); } +void HardwareRenderer::paintOverGL() +{ + // Context switching is needed to make use of QPainter to draw status bar icons in fullscreen. + // Especially since it seems to be impossible to use QPainter on externally-created OpenGL contexts. + if (video_fullscreen && status_icons_fullscreen) + { + m_context->makeCurrent(nullptr); + makeCurrent(); + QPainter painter(this); + drawStatusBarIcons(&painter); + painter.end(); + doneCurrent(); + m_context->makeCurrent(this); + } +} + void HardwareRenderer::paintGL() { m_context->makeCurrent(this); glClear(GL_COLOR_BUFFER_BIT); @@ -200,7 +218,7 @@ void HardwareRenderer::onBlit(int buf_idx, int x, int y, int w, int h) { void HardwareRenderer::resizeEvent(QResizeEvent *event) { onResize(width(), height()); - + QOpenGLWindow::resizeEvent(event); } @@ -214,7 +232,7 @@ bool HardwareRenderer::event(QEvent *event) std::vector> HardwareRenderer::getBuffers() { std::vector> buffers; - + buffers.push_back(std::make_tuple(imagebufs[0].get(), &buf_usage[0])); buffers.push_back(std::make_tuple(imagebufs[1].get(), &buf_usage[1])); diff --git a/src/qt/qt_hardwarerenderer.hpp b/src/qt/qt_hardwarerenderer.hpp index af4f05464..9720a8c2e 100644 --- a/src/qt/qt_hardwarerenderer.hpp +++ b/src/qt/qt_hardwarerenderer.hpp @@ -47,6 +47,7 @@ public: void resizeGL(int w, int h) override; void initializeGL() override; void paintGL() override; + void paintOverGL() override; std::vector> getBuffers() override; HardwareRenderer(QWidget* parent = nullptr, RenderType rtype = RenderType::OpenGL) : QOpenGLWindow(QOpenGLWindow::NoPartialUpdate, parent->windowHandle()), QOpenGLFunctions() diff --git a/src/qt/qt_mainwindow.cpp b/src/qt/qt_mainwindow.cpp index 6a54bf200..8cb107192 100644 --- a/src/qt/qt_mainwindow.cpp +++ b/src/qt/qt_mainwindow.cpp @@ -132,7 +132,7 @@ MainWindow::MainWindow(QWidget *parent) : return; } if (!hide_tool_bar) -#ifdef _WIN32 +#ifdef _WIN32 toolbar_label->setText(title); #else { @@ -187,12 +187,12 @@ MainWindow::MainWindow(QWidget *parent) : connect(this, &MainWindow::resizeContents, this, [this](int w, int h) { if (!QApplication::platformName().contains("eglfs") && vid_resize == 0) { w = qRound(w / (!dpi_scale ? util::screenOfWidget(this)->devicePixelRatio() : 1.)); - + int modifiedHeight = qRound(h / (!dpi_scale ? util::screenOfWidget(this)->devicePixelRatio() : 1.)) + menuBar()->height() + (statusBar()->height() * !hide_status_bar) + (ui->toolBar->height() * !hide_tool_bar); - + ui->stackedWidget->resize(w, h); setFixedSize(w, modifiedHeight); } @@ -225,6 +225,7 @@ MainWindow::MainWindow(QWidget *parent) : ui->actionHide_tool_bar->setChecked(hide_tool_bar); ui->actionUpdate_status_bar_icons->setChecked(update_icons); ui->actionEnable_Discord_integration->setChecked(enable_discord); + ui->actionShow_status_icons_in_fullscreen->setChecked(status_icons_fullscreen); #if defined Q_OS_WINDOWS || defined Q_OS_MACOS /* Make the option visible only if ANGLE is loaded. */ @@ -1614,3 +1615,10 @@ void MainWindow::changeEvent(QEvent* event) #endif QWidget::changeEvent(event); } + +void MainWindow::on_actionShow_status_icons_in_fullscreen_triggered() +{ + status_icons_fullscreen = !status_icons_fullscreen; + ui->actionShow_status_icons_in_fullscreen->setChecked(status_icons_fullscreen); +} + diff --git a/src/qt/qt_mainwindow.hpp b/src/qt/qt_mainwindow.hpp index 3d5a6a02a..90f7ddcff 100644 --- a/src/qt/qt_mainwindow.hpp +++ b/src/qt/qt_mainwindow.hpp @@ -110,6 +110,8 @@ private slots: void on_actionEnable_Discord_integration_triggered(bool checked); + void on_actionShow_status_icons_in_fullscreen_triggered(); + protected: void keyPressEvent(QKeyEvent* event) override; void keyReleaseEvent(QKeyEvent* event) override; @@ -124,7 +126,7 @@ private: Ui::MainWindow *ui; std::unique_ptr status; std::shared_ptr mm; - + /* If main window should send keyboard input */ bool send_keyboard_input = true; bool shownonce = false; diff --git a/src/qt/qt_mainwindow.ui b/src/qt/qt_mainwindow.ui index 6a35279c2..edc692a85 100644 --- a/src/qt/qt_mainwindow.ui +++ b/src/qt/qt_mainwindow.ui @@ -149,6 +149,7 @@ + @@ -697,6 +698,14 @@ false + + + true + + + Show status icons in fullscreen + + diff --git a/src/qt/qt_renderercommon.cpp b/src/qt/qt_renderercommon.cpp index 0974c1f78..e8300dfa0 100644 --- a/src/qt/qt_renderercommon.cpp +++ b/src/qt/qt_renderercommon.cpp @@ -17,17 +17,25 @@ #include "qt_renderercommon.hpp" #include "qt_mainwindow.hpp" +#include "qt_machinestatus.hpp" +#include "ui_qt_mainwindow.h" #include #include #include #include +#include +#include +#include #include extern "C" { #include <86box/86box.h> +#include <86box/plat.h> #include <86box/video.h> + +int status_icons_fullscreen = 0; } RendererCommon::RendererCommon() = default; @@ -101,6 +109,44 @@ void RendererCommon::onResize(int width, int height) { } } +void RendererCommon::drawStatusBarIcons(QPainter* painter) +{ + uint32_t x = 0; + auto prevcompositionMode = painter->compositionMode(); + painter->setCompositionMode(QPainter::CompositionMode::CompositionMode_SourceOver); + for (int i = 0; i < main_window->ui->statusbar->children().count(); i++) + { + QLabel* label = qobject_cast(main_window->ui->statusbar->children()[i]); + if (label) + { + auto pixmap = label->pixmap(Qt::ReturnByValue); + if (!pixmap.isNull()) + { + painter->setBrush(QColor(0, 0, 0, 255)); + painter->fillRect(x, painter->device()->height() - pixmap.height() - 4, pixmap.width(), pixmap.height() + 4, QColor(0, 0, 0, 127)); + painter->drawPixmap(x, painter->device()->height() - pixmap.height(), pixmap); + x += pixmap.width(); + if (i <= main_window->ui->statusbar->children().count() - 3) + { + painter->fillRect(x, painter->device()->height() - pixmap.height() - 4, main_window->ui->statusbar->layout()->spacing(), pixmap.height() + 4, QColor(0, 0, 0, 127)); + x += main_window->ui->statusbar->layout()->spacing(); + } + else painter->fillRect(x, painter->device()->height() - pixmap.height() - 4, 4, pixmap.height() + 4, QColor(0, 0, 0, 127)); + } + } + } + if (main_window->status->getMessage().isEmpty() == false) + { + auto curStatusMsg = main_window->status->getMessage(); + auto textSize = painter->fontMetrics().size(Qt::TextSingleLine, curStatusMsg); + painter->setPen(QColor(0, 0, 0, 127)); + painter->fillRect(painter->device()->width() - textSize.width(), painter->device()->height() - textSize.height(), textSize.width(), textSize.height(), QColor(0, 0, 0, 127)); + painter->setPen(QColor(255, 255, 255, 255)); + painter->drawText(QRectF(painter->device()->width() - textSize.width(), painter->device()->height() - textSize.height(), textSize.width(), textSize.height()), Qt::TextSingleLine, curStatusMsg); + } + painter->setCompositionMode(prevcompositionMode); +} + bool RendererCommon::eventDelegate(QEvent *event, bool& result) { switch (event->type()) diff --git a/src/qt/qt_renderercommon.hpp b/src/qt/qt_renderercommon.hpp index f55f3ee03..fe4d278c7 100644 --- a/src/qt/qt_renderercommon.hpp +++ b/src/qt/qt_renderercommon.hpp @@ -20,6 +20,7 @@ public: virtual std::vector> getBuffers() = 0; protected: bool eventDelegate(QEvent* event, bool& result); + void drawStatusBarIcons(QPainter* painter); QRect source, destination; QWidget* parentWidget{nullptr}; diff --git a/src/qt/qt_softwarerenderer.cpp b/src/qt/qt_softwarerenderer.cpp index 13d727e83..2d260eca3 100644 --- a/src/qt/qt_softwarerenderer.cpp +++ b/src/qt/qt_softwarerenderer.cpp @@ -24,6 +24,7 @@ extern "C" { #include <86box/86box.h> +#include <86box/plat.h> #include <86box/video.h> } @@ -53,7 +54,7 @@ void SoftwareRenderer::onBlit(int buf_idx, int x, int y, int w, int h) { cur_image = buf_idx; buf_usage[(buf_idx + 1) % 2].clear(); - + source.setRect(x, y, w, h), update(); } @@ -83,6 +84,7 @@ void SoftwareRenderer::onPaint(QPaintDevice* device) { #endif painter.setCompositionMode(QPainter::CompositionMode_Plus); painter.drawImage(destination, *images[cur_image], source); + if (video_fullscreen && status_icons_fullscreen) drawStatusBarIcons(&painter); } std::vector> SoftwareRenderer::getBuffers() diff --git a/src/unix/unix.c b/src/unix/unix.c index a93609e2e..11f00b786 100644 --- a/src/unix/unix.c +++ b/src/unix/unix.c @@ -48,6 +48,7 @@ extern wchar_t sdl_win_title[512]; plat_joystick_t plat_joystick_state[MAX_PLAT_JOYSTICKS]; joystick_t joystick_state[MAX_JOYSTICKS]; int joysticks_present; +int status_icons_fullscreen = 0; /* unused. */ SDL_mutex *blitmtx; SDL_threadID eventthread; static int exit_event = 0; @@ -1272,4 +1273,4 @@ void endblit() void ui_sb_mt32lcd(char* str) { -} \ No newline at end of file +} diff --git a/src/win/win_ui.c b/src/win/win_ui.c index 6f0301d09..3e027021d 100644 --- a/src/win/win_ui.c +++ b/src/win/win_ui.c @@ -67,6 +67,7 @@ int fixed_size_x = 0, fixed_size_y = 0; int kbd_req_capture = 0; int hide_status_bar = 0; int hide_tool_bar = 0; +int status_icons_fullscreen = 0; /* unused. */ int dpi = 96; extern char openfilestring[512]; From 611486cb71b72e23e83d2076b2ed5bfdc651142d Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Wed, 16 Feb 2022 14:37:09 +0600 Subject: [PATCH 2/6] qt: Fix compilation with Qt 5 --- src/qt/qt_renderercommon.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/qt/qt_renderercommon.cpp b/src/qt/qt_renderercommon.cpp index e8300dfa0..3ced773d4 100644 --- a/src/qt/qt_renderercommon.cpp +++ b/src/qt/qt_renderercommon.cpp @@ -119,7 +119,11 @@ void RendererCommon::drawStatusBarIcons(QPainter* painter) QLabel* label = qobject_cast(main_window->ui->statusbar->children()[i]); if (label) { - auto pixmap = label->pixmap(Qt::ReturnByValue); +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + const QPixmap pixmap = label->pixmap(); +#else + const QPixmap pixmap = *label->pixmap(); +#endif if (!pixmap.isNull()) { painter->setBrush(QColor(0, 0, 0, 255)); From ab4c68402dfcce87ca82580098c36a706d23ec68 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Wed, 16 Feb 2022 14:57:22 +0600 Subject: [PATCH 3/6] qt: Fix crash on fullscreen with status icons enabled --- src/qt/qt_renderercommon.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/qt/qt_renderercommon.cpp b/src/qt/qt_renderercommon.cpp index 3ced773d4..82856d206 100644 --- a/src/qt/qt_renderercommon.cpp +++ b/src/qt/qt_renderercommon.cpp @@ -122,7 +122,7 @@ void RendererCommon::drawStatusBarIcons(QPainter* painter) #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) const QPixmap pixmap = label->pixmap(); #else - const QPixmap pixmap = *label->pixmap(); + const QPixmap pixmap = label->pixmap() ? *label->pixmap() : QPixmap(); #endif if (!pixmap.isNull()) { From ed9b67c4335d4c3a6dfbca8acc9e564617f4148c Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Wed, 16 Feb 2022 15:56:37 +0600 Subject: [PATCH 4/6] qt: Improve appearance of text and status icons in fullscreen --- src/qt/qt_renderercommon.cpp | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/src/qt/qt_renderercommon.cpp b/src/qt/qt_renderercommon.cpp index 82856d206..d08fe9a26 100644 --- a/src/qt/qt_renderercommon.cpp +++ b/src/qt/qt_renderercommon.cpp @@ -18,7 +18,6 @@ #include "qt_renderercommon.hpp" #include "qt_mainwindow.hpp" #include "qt_machinestatus.hpp" -#include "ui_qt_mainwindow.h" #include #include @@ -114,9 +113,9 @@ void RendererCommon::drawStatusBarIcons(QPainter* painter) uint32_t x = 0; auto prevcompositionMode = painter->compositionMode(); painter->setCompositionMode(QPainter::CompositionMode::CompositionMode_SourceOver); - for (int i = 0; i < main_window->ui->statusbar->children().count(); i++) + for (int i = 0; i < main_window->statusBar()->children().count(); i++) { - QLabel* label = qobject_cast(main_window->ui->statusbar->children()[i]); + QLabel* label = qobject_cast(main_window->statusBar()->children()[i]); if (label) { #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) @@ -127,13 +126,13 @@ void RendererCommon::drawStatusBarIcons(QPainter* painter) if (!pixmap.isNull()) { painter->setBrush(QColor(0, 0, 0, 255)); - painter->fillRect(x, painter->device()->height() - pixmap.height() - 4, pixmap.width(), pixmap.height() + 4, QColor(0, 0, 0, 127)); - painter->drawPixmap(x, painter->device()->height() - pixmap.height(), pixmap); + painter->fillRect(x, painter->device()->height() - pixmap.height() - 5, pixmap.width(), pixmap.height() + 5, QColor(0, 0, 0, 127)); + painter->drawPixmap(x + main_window->statusBar()->layout()->spacing() / 2, painter->device()->height() - pixmap.height() - 3, pixmap); x += pixmap.width(); - if (i <= main_window->ui->statusbar->children().count() - 3) + if (i <= main_window->statusBar()->children().count() - 3) { - painter->fillRect(x, painter->device()->height() - pixmap.height() - 4, main_window->ui->statusbar->layout()->spacing(), pixmap.height() + 4, QColor(0, 0, 0, 127)); - x += main_window->ui->statusbar->layout()->spacing(); + painter->fillRect(x, painter->device()->height() - pixmap.height() - 5, main_window->statusBar()->layout()->spacing(), pixmap.height() + 5, QColor(0, 0, 0, 127)); + x += main_window->statusBar()->layout()->spacing(); } else painter->fillRect(x, painter->device()->height() - pixmap.height() - 4, 4, pixmap.height() + 4, QColor(0, 0, 0, 127)); } @@ -142,11 +141,11 @@ void RendererCommon::drawStatusBarIcons(QPainter* painter) if (main_window->status->getMessage().isEmpty() == false) { auto curStatusMsg = main_window->status->getMessage(); - auto textSize = painter->fontMetrics().size(Qt::TextSingleLine, curStatusMsg); + auto textSize = painter->fontMetrics().size(Qt::TextSingleLine, QChar(' ') + curStatusMsg + QChar(' ')); painter->setPen(QColor(0, 0, 0, 127)); painter->fillRect(painter->device()->width() - textSize.width(), painter->device()->height() - textSize.height(), textSize.width(), textSize.height(), QColor(0, 0, 0, 127)); painter->setPen(QColor(255, 255, 255, 255)); - painter->drawText(QRectF(painter->device()->width() - textSize.width(), painter->device()->height() - textSize.height(), textSize.width(), textSize.height()), Qt::TextSingleLine, curStatusMsg); + painter->drawText(QRectF(painter->device()->width() - textSize.width(), painter->device()->height() - textSize.height(), textSize.width(), textSize.height()), Qt::TextSingleLine, QChar(' ') + curStatusMsg + QChar(' ')); } painter->setCompositionMode(prevcompositionMode); } From 9e0ca23060baacf8fa82fec7f16aa28ab42fc801 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Wed, 16 Feb 2022 16:10:54 +0600 Subject: [PATCH 5/6] qt: Construct colors from floating point values --- src/qt/qt_renderercommon.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/qt/qt_renderercommon.cpp b/src/qt/qt_renderercommon.cpp index d08fe9a26..82fa78628 100644 --- a/src/qt/qt_renderercommon.cpp +++ b/src/qt/qt_renderercommon.cpp @@ -125,16 +125,17 @@ void RendererCommon::drawStatusBarIcons(QPainter* painter) #endif if (!pixmap.isNull()) { - painter->setBrush(QColor(0, 0, 0, 255)); - painter->fillRect(x, painter->device()->height() - pixmap.height() - 5, pixmap.width(), pixmap.height() + 5, QColor(0, 0, 0, 127)); + painter->setBrush(QColor::fromRgbF(0, 0, 0, 1.)); + painter->fillRect(x, painter->device()->height() - pixmap.height() - 5, pixmap.width(), pixmap.height() + 5, QColor::fromRgbF(0, 0, 0, .5)); painter->drawPixmap(x + main_window->statusBar()->layout()->spacing() / 2, painter->device()->height() - pixmap.height() - 3, pixmap); x += pixmap.width(); if (i <= main_window->statusBar()->children().count() - 3) { - painter->fillRect(x, painter->device()->height() - pixmap.height() - 5, main_window->statusBar()->layout()->spacing(), pixmap.height() + 5, QColor(0, 0, 0, 127)); + painter->fillRect(x, painter->device()->height() - pixmap.height() - 5, main_window->statusBar()->layout()->spacing(), pixmap.height() + 5, QColor::fromRgbF(0, 0, 0, .5)); x += main_window->statusBar()->layout()->spacing(); } - else painter->fillRect(x, painter->device()->height() - pixmap.height() - 4, 4, pixmap.height() + 4, QColor(0, 0, 0, 127)); + else painter->fillRect(x, painter->device()->height() - pixmap.height() - 4, 4, pixmap.height() + 4, QColor::fromRgbF(0, 0, 0, .5)); + pixheight = qMax((unsigned int)pixheight, (unsigned int)pixmap.height()); } } } From d25a16eedbe5bae33abd3b4f4efa14e8ba429a49 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Wed, 16 Feb 2022 16:19:55 +0600 Subject: [PATCH 6/6] qt: Fix compile error --- src/qt/qt_renderercommon.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/qt/qt_renderercommon.cpp b/src/qt/qt_renderercommon.cpp index 82fa78628..c76067add 100644 --- a/src/qt/qt_renderercommon.cpp +++ b/src/qt/qt_renderercommon.cpp @@ -135,7 +135,6 @@ void RendererCommon::drawStatusBarIcons(QPainter* painter) x += main_window->statusBar()->layout()->spacing(); } else painter->fillRect(x, painter->device()->height() - pixmap.height() - 4, 4, pixmap.height() + 4, QColor::fromRgbF(0, 0, 0, .5)); - pixheight = qMax((unsigned int)pixheight, (unsigned int)pixmap.height()); } } }