2022-02-07 15:00:02 +06:00
/*
2023-01-06 15:36:05 -05:00
* 86 Box A hypervisor and IBM PC system emulator that specializes in
* running old operating systems and software designed for IBM
* PC systems and compatibles from 1981 through fairly recent
* system designs based on the PCI bus .
2022-02-07 15:00:02 +06:00
*
2023-01-06 15:36:05 -05:00
* This file is part of the 86 Box distribution .
2022-02-07 15:00:02 +06:00
*
2023-01-06 15:36:05 -05:00
* Main window module .
2022-02-07 15:00:02 +06:00
*
*
*
2023-01-06 15:36:05 -05:00
* Authors : Joakim L . Gilje < jgilje @ jgilje . net >
2022-02-07 15:00:02 +06:00
* Cacodemon345
* Teemu Korhonen
2022-02-07 15:35:15 +06:00
* dob205
2022-02-07 15:00:02 +06:00
*
2023-01-06 15:36:05 -05:00
* Copyright 2021 Joakim L . Gilje
* Copyright 2021 - 2022 Cacodemon345
* Copyright 2021 - 2022 Teemu Korhonen
* Copyright 2022 dob205
2022-02-07 15:00:02 +06:00
*/
2022-07-05 15:32:50 +06:00
# include <QDebug>
2021-11-25 10:20:56 +01:00
# include "qt_mainwindow.hpp"
# include "ui_qt_mainwindow.h"
2021-12-12 01:16:27 +06:00
# include "qt_specifydimensions.h"
2021-12-12 16:22:35 +06:00
# include "qt_soundgain.hpp"
2021-12-28 16:47:10 +06:00
# include "qt_progsettings.hpp"
2022-05-23 17:29:45 +06:00
# include "qt_mcadevicelist.hpp"
2021-12-12 01:16:27 +06:00
2021-12-27 16:32:03 +06:00
# include "qt_rendererstack.hpp"
2022-01-30 22:13:41 +02:00
# include "qt_renderercommon.hpp"
2021-12-27 16:32:03 +06:00
2025-08-21 02:32:36 +06:00
# include "qt_cgasettingsdialog.hpp"
2021-11-25 10:20:56 +01:00
extern " C " {
# include <86box/86box.h>
# include <86box/config.h>
2021-11-30 16:26:49 +06:00
# include <86box/keyboard.h>
2021-11-25 10:20:56 +01:00
# include <86box/plat.h>
2022-07-09 13:51:12 +06:00
# include <86box/ui.h>
2023-02-01 17:17:56 +01:00
# ifdef DISCORD
# include <86box / discord.h>
# endif
2022-07-12 14:41:38 +06:00
# include <86box/device.h>
2021-11-30 16:26:49 +06:00
# include <86box/video.h>
2023-01-03 15:42:57 +06:00
# include <86box/mouse.h>
2022-06-04 14:15:31 +06:00
# include <86box/machine.h>
2021-12-09 11:55:28 +01:00
# include <86box/vid_ega.h>
2021-12-09 20:10:23 +01:00
# include <86box/version.h>
2025-03-06 19:34:24 +06:00
# include <86box/timer.h>
# include <86box/apm.h>
# include <86box/nvr.h>
# include <86box/acpi.h>
2025-06-28 18:48:30 -04:00
# include <86box/renderdefs.h>
2022-02-04 15:19:18 +06:00
2022-08-03 13:05:21 +06:00
# ifdef USE_VNC
2022-11-19 08:49:04 -05:00
# include <86box / vnc.h>
2022-08-03 13:05:21 +06:00
# endif
2022-11-19 08:49:04 -05:00
extern int qt_nvr_save ( void ) ;
2022-02-12 17:31:28 +02:00
2022-02-04 15:19:18 +06:00
# ifdef MTR_ENABLED
2022-11-19 08:49:04 -05:00
# include <minitrace / minitrace.h>
2022-02-04 15:19:18 +06:00
# endif
2025-03-10 13:27:29 +06:00
extern bool cpu_thread_running ;
2021-11-25 10:20:56 +01:00
} ;
2021-12-06 10:41:14 +01:00
# include <QGuiApplication>
2021-11-25 10:20:56 +01:00
# include <QWindow>
# include <QTimer>
2021-11-29 17:25:31 +01:00
# include <QThread>
2021-11-25 10:20:56 +01:00
# include <QKeyEvent>
2023-07-24 15:05:29 -03:00
# include <QShortcut>
2021-11-29 12:25:27 +01:00
# include <QMessageBox>
2021-12-05 15:57:46 +06:00
# include <QFocusEvent>
2021-12-09 16:27:53 +06:00
# include <QApplication>
# include <QPushButton>
# include <QDesktopServices>
# include <QUrl>
2022-07-10 11:41:02 +06:00
# include <QMenuBar>
2021-12-12 01:16:27 +06:00
# include <QCheckBox>
2021-12-18 01:03:05 +06:00
# include <QActionGroup>
2021-12-27 14:25:18 +02:00
# include <QOpenGLContext>
2021-12-30 23:36:49 +06:00
# include <QScreen>
2022-01-13 09:28:38 +02:00
# include <QString>
2022-08-09 15:35:32 +06:00
# include <QDir>
2022-12-29 00:50:50 +06:00
# include <QSysInfo>
2022-11-03 21:58:54 +06:00
# if QT_CONFIG(vulkan)
2022-11-19 08:49:04 -05:00
# include <QVulkanInstance>
# include <QVulkanFunctions>
2022-11-03 21:58:54 +06:00
# endif
2021-11-25 10:20:56 +01:00
2025-08-01 02:31:29 +05:00
void qt_set_sequence_auto_mnemonic ( bool b ) ;
2021-11-30 16:26:49 +06:00
# include <array>
2024-05-03 17:02:13 +02:00
# include <memory>
2021-12-06 10:41:14 +01:00
# include <unordered_map>
2021-11-30 16:26:49 +06:00
2021-11-25 10:20:56 +01:00
# include "qt_settings.hpp"
2025-07-27 04:31:13 +05:00
# include "qt_about.hpp"
2021-11-30 22:06:41 +01:00
# include "qt_machinestatus.hpp"
2021-12-03 11:38:00 +01:00
# include "qt_mediamenu.hpp"
2022-02-10 15:30:39 +06:00
# include "qt_util.hpp"
2021-11-30 16:26:49 +06:00
2022-03-11 12:03:54 +06:00
# if defined __unix__ && !defined __HAIKU__
2023-04-08 17:58:55 -03:00
# ifndef Q_OS_MACOS
# include "evdev_keyboard.hpp"
# endif
2023-04-07 22:33:53 -03:00
# ifdef XKBCOMMON
# include "xkbcommon_keyboard.hpp"
# ifdef XKBCOMMON_X11
# include "xkbcommon_x11_keyboard.hpp"
# endif
2023-04-08 00:31:25 -03:00
# ifdef WAYLAND
# include "xkbcommon_wl_keyboard.hpp"
# endif
2022-11-19 08:49:04 -05:00
# endif
# include <X11 / Xlib.h>
# include <X11 / keysym.h>
# undef KeyPress
# undef KeyRelease
2021-12-27 16:32:03 +06:00
# endif
2021-11-30 16:26:49 +06:00
2023-11-21 23:37:50 +01:00
# if defined Q_OS_UNIX && !defined Q_OS_HAIKU && !defined Q_OS_MACOS
# include <qpa/qplatformwindow.h>
# include "x11_util.h"
# endif
2022-03-19 23:06:17 +00:00
# ifdef Q_OS_MACOS
2023-04-09 17:48:13 -03:00
# include "cocoa_keyboard.hpp"
2022-03-19 23:06:17 +00:00
// The namespace is required to avoid clashing typedefs; we only use this
// header for its #defines anyway.
namespace IOKit {
2022-11-19 08:49:04 -05:00
# include <IOKit / hidsystem / IOLLEvent.h>
2022-03-19 23:06:17 +00:00
}
2021-11-30 16:26:49 +06:00
# endif
2022-03-11 12:03:54 +06:00
# ifdef __HAIKU__
2022-11-19 08:49:04 -05:00
# include <os / AppKit.h>
# include <os / InterfaceKit.h>
2023-04-09 18:08:03 -03:00
# include "be_keyboard.hpp"
2021-11-25 10:20:56 +01:00
2022-11-19 08:49:04 -05:00
extern MainWindow * main_window ;
2025-04-19 19:44:47 -07:00
QShortcut * windowedShortcut ;
2022-03-11 12:03:54 +06:00
2022-11-19 08:49:04 -05:00
filter_result
keyb_filter ( BMessage * message , BHandler * * target , BMessageFilter * filter )
2021-11-25 10:20:56 +01:00
{
2022-03-11 12:03:54 +06:00
if ( message - > what = = B_KEY_DOWN | | message - > what = = B_KEY_UP
2022-11-19 08:49:04 -05:00
| | message - > what = = B_UNMAPPED_KEY_DOWN | | message - > what = = B_UNMAPPED_KEY_UP ) {
2022-03-11 12:03:54 +06:00
int key_state = 0 , key_scancode = 0 ;
key_state = message - > what = = B_KEY_DOWN | | message - > what = = B_UNMAPPED_KEY_DOWN ;
message - > FindInt32 ( " key " , & key_scancode ) ;
QGuiApplication : : postEvent ( main_window , new QKeyEvent ( key_state ? QEvent : : KeyPress : QEvent : : KeyRelease , 0 , QGuiApplication : : keyboardModifiers ( ) , key_scancode , 0 , 0 ) ) ;
2022-11-19 08:49:04 -05:00
if ( key_scancode = = 0x68 & & key_state ) {
2022-03-11 12:03:54 +06:00
QGuiApplication : : postEvent ( main_window , new QKeyEvent ( QEvent : : KeyRelease , 0 , QGuiApplication : : keyboardModifiers ( ) , key_scancode , 0 , 0 ) ) ;
}
}
return B_DISPATCH_MESSAGE ;
}
2022-11-19 08:49:04 -05:00
static BMessageFilter * filter ;
2022-03-11 12:03:54 +06:00
# endif
2022-11-19 08:49:04 -05:00
extern void qt_mouse_capture ( int ) ;
2022-07-03 01:07:13 +06:00
extern " C " void qt_blit ( int x , int y , int w , int h , int monitor_index ) ;
2021-11-25 10:20:56 +01:00
2022-11-19 08:49:04 -05:00
extern MainWindow * main_window ;
2022-08-10 01:27:54 +06:00
2022-11-19 08:49:04 -05:00
MainWindow : : MainWindow ( QWidget * parent )
: QMainWindow ( parent )
, ui ( new Ui : : MainWindow )
2021-11-25 10:20:56 +01:00
{
2022-11-19 08:49:04 -05:00
mm = std : : make_shared < MediaMenu > ( this ) ;
2021-12-03 11:38:00 +01:00
MediaMenu : : ptr = mm ;
2022-11-19 08:49:04 -05:00
status = std : : make_unique < MachineStatus > ( this ) ;
2021-11-25 10:20:56 +01:00
2022-03-11 12:03:54 +06:00
# ifdef __HAIKU__
filter = new BMessageFilter ( B_PROGRAMMED_DELIVERY , B_ANY_SOURCE , keyb_filter ) ;
2022-11-19 08:49:04 -05:00
( ( BWindow * ) this - > winId ( ) ) - > AddFilter ( filter ) ;
2022-03-11 12:03:54 +06:00
# endif
2022-01-20 20:19:18 +02:00
setUnifiedTitleAndToolBarOnMac ( true ) ;
2022-11-19 08:49:04 -05:00
extern MainWindow * main_window ;
2022-08-03 13:05:21 +06:00
main_window = this ;
2021-11-25 10:20:56 +01:00
ui - > setupUi ( this ) ;
2025-04-11 05:26:01 +05:00
status - > setSoundMenu ( ui - > menuSound ) ;
ui - > actionMute_Unmute - > setText ( sound_muted ? tr ( " &Unmute " ) : tr ( " &Mute " ) ) ;
2025-03-16 16:55:29 +05:00
ui - > menuEGA_S_VGA_settings - > menuAction ( ) - > setMenuRole ( QAction : : NoRole ) ;
2021-12-04 21:33:04 +01:00
ui - > stackedWidget - > setMouseTracking ( true ) ;
2021-12-12 01:16:27 +06:00
statusBar ( ) - > setVisible ( ! hide_status_bar ) ;
2025-03-27 16:31:32 +06:00
2025-08-16 23:23:57 -03:00
auto hertz_label = new QLabel ;
QTimer * frameRateTimer = new QTimer ( this ) ;
frameRateTimer - > setInterval ( 1000 ) ;
frameRateTimer - > setSingleShot ( false ) ;
2025-08-24 01:11:54 +02:00
connect ( frameRateTimer , & QTimer : : timeout , [ hertz_label ] {
2025-08-18 23:35:09 +06:00
hertz_label - > setText ( tr ( " %1 Hz " ) . arg ( QString : : number ( monitors [ 0 ] . mon_actualrenderedframes . load ( ) ) + ( monitors [ 0 ] . mon_interlace ? " i " : " " ) ) ) ;
2025-08-16 23:23:57 -03:00
} ) ;
statusBar ( ) - > addPermanentWidget ( hertz_label ) ;
frameRateTimer - > start ( 1000 ) ;
2025-05-06 13:06:44 +06:00
num_icon = QIcon ( " :/settings/qt/icons/num_lock_on.ico " ) ;
num_icon_off = QIcon ( " :/settings/qt/icons/num_lock_off.ico " ) ;
scroll_icon = QIcon ( " :/settings/qt/icons/scroll_lock_on.ico " ) ;
scroll_icon_off = QIcon ( " :/settings/qt/icons/scroll_lock_off.ico " ) ;
caps_icon = QIcon ( " :/settings/qt/icons/caps_lock_on.ico " ) ;
caps_icon_off = QIcon ( " :/settings/qt/icons/caps_lock_off.ico " ) ;
2025-05-07 01:54:34 +02:00
kana_icon = QIcon ( " :/settings/qt/icons/kana_lock_on.ico " ) ;
kana_icon_off = QIcon ( " :/settings/qt/icons/kana_lock_off.ico " ) ;
2025-05-06 13:06:44 +06:00
2025-03-27 16:31:32 +06:00
num_label = new QLabel ;
2025-05-06 13:06:44 +06:00
num_label - > setPixmap ( num_icon_off . pixmap ( QSize ( 16 , 16 ) ) ) ;
2025-05-08 00:28:25 +06:00
num_label - > setToolTip ( QShortcut : : tr ( " Num Lock " ) ) ;
2025-03-27 16:31:32 +06:00
statusBar ( ) - > addPermanentWidget ( num_label ) ;
caps_label = new QLabel ;
2025-05-06 13:06:44 +06:00
caps_label - > setPixmap ( caps_icon_off . pixmap ( QSize ( 16 , 16 ) ) ) ;
2025-05-08 00:28:25 +06:00
caps_label - > setToolTip ( QShortcut : : tr ( " Caps Lock " ) ) ;
2025-03-27 16:31:32 +06:00
statusBar ( ) - > addPermanentWidget ( caps_label ) ;
2025-03-27 16:58:42 +06:00
scroll_label = new QLabel ;
2025-05-06 13:06:44 +06:00
scroll_label - > setPixmap ( scroll_icon_off . pixmap ( QSize ( 16 , 16 ) ) ) ;
2025-05-08 00:28:25 +06:00
scroll_label - > setToolTip ( QShortcut : : tr ( " Scroll Lock " ) ) ;
2025-03-27 16:58:42 +06:00
statusBar ( ) - > addPermanentWidget ( scroll_label ) ;
2025-05-07 01:54:34 +02:00
kana_label = new QLabel ;
kana_label - > setPixmap ( kana_icon_off . pixmap ( QSize ( 16 , 16 ) ) ) ;
2025-05-08 00:28:25 +06:00
kana_label - > setToolTip ( QShortcut : : tr ( " Kana Lock " ) ) ;
2025-05-07 01:54:34 +02:00
statusBar ( ) - > addPermanentWidget ( kana_label ) ;
2025-03-27 16:31:32 +06:00
QTimer * ledKeyboardTimer = new QTimer ( this ) ;
ledKeyboardTimer - > setTimerType ( Qt : : CoarseTimer ) ;
ledKeyboardTimer - > setInterval ( 1 ) ;
connect ( ledKeyboardTimer , & QTimer : : timeout , this , [ this ] ( ) {
2025-05-07 01:54:34 +02:00
uint8_t caps , num , scroll , kana ;
keyboard_get_states ( & caps , & num , & scroll , & kana ) ;
2025-05-06 13:06:44 +06:00
if ( num_label - > isVisible ( ) )
num_label - > setPixmap ( num ? this - > num_icon . pixmap ( QSize ( 16 , 16 ) ) : this - > num_icon_off . pixmap ( QSize ( 16 , 16 ) ) ) ;
if ( caps_label - > isVisible ( ) )
caps_label - > setPixmap ( caps ? this - > caps_icon . pixmap ( QSize ( 16 , 16 ) ) : this - > caps_icon_off . pixmap ( QSize ( 16 , 16 ) ) ) ;
if ( scroll_label - > isVisible ( ) )
2025-05-07 01:54:34 +02:00
scroll_label - > setPixmap ( scroll ? this - > scroll_icon . pixmap ( QSize ( 16 , 16 ) ) :
this - > scroll_icon_off . pixmap ( QSize ( 16 , 16 ) ) ) ;
if ( kana_label - > isVisible ( ) )
kana_label - > setPixmap ( kana ? this - > kana_icon . pixmap ( QSize ( 16 , 16 ) ) :
this - > kana_icon_off . pixmap ( QSize ( 16 , 16 ) ) ) ;
2025-03-27 16:31:32 +06:00
} ) ;
ledKeyboardTimer - > start ( ) ;
2025-03-01 15:54:50 +05:00
# ifdef Q_OS_WINDOWS
2025-03-07 00:11:45 +05:00
util : : setWin11RoundedCorners ( this - > winId ( ) , ( hide_status_bar ? false : true ) ) ;
2025-03-01 15:54:50 +05:00
# endif
2022-01-10 19:15:07 +02:00
statusBar ( ) - > setStyleSheet ( " QStatusBar::item {border: None; } QStatusBar QLabel { margin-right: 2px; margin-bottom: 1px; } " ) ;
2022-10-31 13:30:19 +06:00
this - > centralWidget ( ) - > setStyleSheet ( " background-color: black; " ) ;
2022-01-09 17:00:16 +02:00
ui - > toolBar - > setVisible ( ! hide_tool_bar ) ;
2022-11-11 21:58:42 +06:00
# ifdef _WIN32
ui - > toolBar - > setBackgroundRole ( QPalette : : Light ) ;
# endif
2022-07-04 01:50:42 +06:00
renderers [ 0 ] . reset ( nullptr ) ;
2022-01-13 08:33:29 +02:00
auto toolbar_spacer = new QWidget ( ) ;
toolbar_spacer - > setSizePolicy ( QSizePolicy : : Expanding , QSizePolicy : : Expanding ) ;
ui - > toolBar - > addWidget ( toolbar_spacer ) ;
2022-01-22 22:02:57 +02:00
auto toolbar_label = new QLabel ( ) ;
2022-01-13 08:33:29 +02:00
ui - > toolBar - > addWidget ( toolbar_label ) ;
2021-12-24 01:57:26 +06:00
this - > setWindowFlag ( Qt : : MSWindowsFixedSizeDialogHint , vid_resize ! = 1 ) ;
this - > setWindowFlag ( Qt : : WindowMaximizeButtonHint , vid_resize = = 1 ) ;
2021-12-09 16:27:53 +06:00
2022-02-10 16:55:38 +06:00
QString vmname ( vm_name ) ;
2022-11-19 08:49:04 -05:00
if ( vmname . at ( vmname . size ( ) - 1 ) = = ' " ' | | vmname . at ( vmname . size ( ) - 1 ) = = ' \' ' )
vmname . truncate ( vmname . size ( ) - 1 ) ;
2022-02-10 16:55:38 +06:00
this - > setWindowTitle ( QString ( " %1 - %2 %3 " ) . arg ( vmname , EMU_NAME , EMU_VERSION_FULL ) ) ;
2022-01-13 08:33:29 +02:00
2023-01-03 15:42:57 +06:00
connect ( this , & MainWindow : : hardResetCompleted , this , [ this ] ( ) {
ui - > actionMCA_devices - > setVisible ( machine_has_bus ( machine , MACHINE_BUS_MCA ) ) ;
2025-05-06 13:06:44 +06:00
num_label - > setVisible ( machine_has_bus ( machine , MACHINE_BUS_PS2_PORTS | MACHINE_BUS_AT_KBD ) ) ;
scroll_label - > setVisible ( machine_has_bus ( machine , MACHINE_BUS_PS2_PORTS | MACHINE_BUS_AT_KBD ) ) ;
caps_label - > setVisible ( machine_has_bus ( machine , MACHINE_BUS_PS2_PORTS | MACHINE_BUS_AT_KBD ) ) ;
2025-07-27 15:23:43 +02:00
int ext_ax_kbd = machine_has_bus ( machine , MACHINE_BUS_PS2_PORTS | MACHINE_BUS_AT_KBD ) & &
( keyboard_type = = KEYBOARD_TYPE_AX ) ;
int int_ax_kbd = machine_has_flags ( machine , MACHINE_KEYBOARD_JIS ) & &
! machine_has_bus ( machine , MACHINE_BUS_PS2_PORTS ) ;
kana_label - > setVisible ( ext_ax_kbd | | int_ax_kbd ) ;
2024-05-04 23:36:09 +06:00
while ( QApplication : : overrideCursor ( ) )
QApplication : : restoreOverrideCursor ( ) ;
2023-10-13 23:30:31 +02:00
# ifdef USE_WACOM
2023-10-23 01:21:28 +02:00
ui - > menuTablet_tool - > menuAction ( ) - > setVisible ( mouse_input_mode > = 1 ) ;
2023-10-13 23:30:31 +02:00
# else
ui - > menuTablet_tool - > menuAction ( ) - > setVisible ( false ) ;
# endif
2025-08-21 02:32:36 +06:00
bool enable_comp_option = false ;
for ( int i = 0 ; i < MONITORS_NUM ; i + + ) {
if ( monitors [ i ] . mon_composite ) { enable_comp_option = true ; break ; }
}
ui - > actionCGA_composite_settings - > setEnabled ( enable_comp_option ) ;
2023-01-03 15:42:57 +06:00
} ) ;
2024-06-26 23:09:55 +02:00
connect ( this , & MainWindow : : showMessageForNonQtThread , this , & MainWindow : : showMessage_ , Qt : : QueuedConnection ) ;
2021-11-29 12:25:27 +01:00
2025-08-24 01:11:54 +02:00
connect ( this , & MainWindow : : setTitle , this , [ toolbar_label ] ( const QString & title ) {
2022-11-19 08:49:04 -05:00
if ( dopause & & ! hide_tool_bar ) {
2022-02-13 07:03:37 +05:00
toolbar_label - > setText ( toolbar_label - > text ( ) + tr ( " - PAUSED " ) ) ;
2022-02-13 00:36:47 +06:00
return ;
}
2022-01-13 08:33:29 +02:00
if ( ! hide_tool_bar )
2022-02-16 01:09:11 +06:00
# ifdef _WIN32
2022-01-13 08:33:29 +02:00
toolbar_label - > setText ( title ) ;
2022-01-14 20:25:17 +02:00
# else
{
/* get the percentage and mouse message, TODO: refactor ui_window_title() */
auto parts = title . split ( " - " ) ;
2022-02-05 02:04:32 +06:00
if ( parts . size ( ) > = 2 ) {
if ( parts . size ( ) < 5 )
toolbar_label - > setText ( parts [ 1 ] ) ;
else
toolbar_label - > setText ( QString ( " %1 - %2 " ) . arg ( parts [ 1 ] , parts . last ( ) ) ) ;
}
2022-01-14 20:25:17 +02:00
}
# endif
2021-12-14 20:30:09 +01:00
} ) ;
2021-12-01 15:55:41 +06:00
connect ( this , & MainWindow : : getTitleForNonQtThread , this , & MainWindow : : getTitle_ , Qt : : BlockingQueuedConnection ) ;
2021-12-12 01:16:27 +06:00
connect ( this , & MainWindow : : updateMenuResizeOptions , [ this ] ( ) {
ui - > actionResizable_window - > setEnabled ( vid_resize ! = 2 ) ;
ui - > actionResizable_window - > setChecked ( vid_resize = = 1 ) ;
ui - > menuWindow_scale_factor - > setEnabled ( vid_resize = = 0 ) ;
} ) ;
connect ( this , & MainWindow : : updateWindowRememberOption , [ this ] ( ) {
ui - > actionRemember_size_and_position - > setChecked ( window_remember ) ;
} ) ;
emit updateMenuResizeOptions ( ) ;
2021-11-30 16:26:49 +06:00
connect ( this , & MainWindow : : setMouseCapture , this , [ this ] ( bool state ) {
2021-11-25 10:20:56 +01:00
mouse_capture = state ? 1 : 0 ;
2021-11-30 16:26:49 +06:00
qt_mouse_capture ( mouse_capture ) ;
2021-12-02 16:26:33 +06:00
if ( mouse_capture ) {
2025-05-09 14:56:55 +06:00
if ( hook_enabled )
this - > grabKeyboard ( ) ;
2022-04-21 13:56:39 -03:00
if ( ui - > stackedWidget - > mouse_capture_func )
ui - > stackedWidget - > mouse_capture_func ( this - > windowHandle ( ) ) ;
2021-12-02 16:26:33 +06:00
} else {
2025-05-11 22:01:24 +06:00
this - > releaseKeyboard ( ) ;
2025-02-27 16:31:27 +06:00
if ( ui - > stackedWidget - > mouse_uncapture_func ) {
2022-04-21 13:56:39 -03:00
ui - > stackedWidget - > mouse_uncapture_func ( ) ;
2025-02-27 16:31:27 +06:00
}
ui - > stackedWidget - > unsetCursor ( ) ;
2021-12-02 16:26:33 +06:00
}
2025-08-01 02:31:29 +05:00
# ifndef Q_OS_MACOS
if ( kbd_req_capture ) {
qt_set_sequence_auto_mnemonic ( ! mouse_capture ) ;
/* Hack to get the menubar to update the internal Alt+shortcut table */
if ( ! video_fullscreen ) {
ui - > menubar - > hide ( ) ;
ui - > menubar - > show ( ) ;
}
}
# endif
2021-11-25 10:20:56 +01:00
} ) ;
2022-03-16 18:19:44 +02:00
connect ( qApp , & QGuiApplication : : applicationStateChanged , [ this ] ( Qt : : ApplicationState state ) {
2023-10-13 23:30:31 +02:00
if ( state = = Qt : : ApplicationState : : ApplicationActive ) {
if ( auto_paused ) {
plat_pause ( 0 ) ;
auto_paused = 0 ;
}
} else {
if ( mouse_capture )
emit setMouseCapture ( false ) ;
2025-02-26 11:39:04 +06:00
keyboard_all_up ( ) ;
2023-10-13 23:30:31 +02:00
if ( do_auto_pause & & ! dopause ) {
auto_paused = 1 ;
plat_pause ( 1 ) ;
2021-12-02 16:26:33 +06:00
}
}
2021-11-25 10:20:56 +01:00
} ) ;
connect ( this , & MainWindow : : resizeContents , this , [ this ] ( int w , int h ) {
2022-07-16 12:57:35 +06:00
if ( shownonce ) {
2022-11-19 08:49:04 -05:00
if ( resizableonce = = false )
ui - > stackedWidget - > setFixedSize ( QWIDGETSIZE_MAX , QWIDGETSIZE_MAX ) ;
2022-07-16 12:57:35 +06:00
resizableonce = true ;
}
2022-07-04 17:54:38 +06:00
if ( ! QApplication : : platformName ( ) . contains ( " eglfs " ) & & vid_resize ! = 1 ) {
2024-05-03 17:02:13 +02:00
w = static_cast < int > ( w / ( ! dpi_scale ? util : : screenOfWidget ( this ) - > devicePixelRatio ( ) : 1. ) ) ;
2022-02-16 01:09:11 +06:00
2024-05-03 17:02:13 +02:00
const int modifiedHeight =
static_cast < int > ( h / ( ! dpi_scale ? util : : screenOfWidget ( this ) - > devicePixelRatio ( ) : 1. ) )
2022-01-09 17:00:16 +02:00
+ menuBar ( ) - > height ( )
+ ( statusBar ( ) - > height ( ) * ! hide_status_bar )
+ ( ui - > toolBar - > height ( ) * ! hide_tool_bar ) ;
2022-02-16 01:09:11 +06:00
2024-05-03 17:02:13 +02:00
ui - > stackedWidget - > resize ( w , static_cast < int > ( h / ( ! dpi_scale ? util : : screenOfWidget ( this ) - > devicePixelRatio ( ) : 1. ) ) ) ;
2022-02-11 00:52:25 +06:00
setFixedSize ( w , modifiedHeight ) ;
2021-12-05 20:51:59 +01:00
}
2021-11-25 10:20:56 +01:00
} ) ;
2022-11-19 08:49:04 -05:00
connect ( this , & MainWindow : : resizeContentsMonitor , this , [ this ] ( int w , int h , int monitor_index ) {
2022-07-04 17:54:38 +06:00
if ( ! QApplication : : platformName ( ) . contains ( " eglfs " ) & & vid_resize ! = 1 ) {
2023-08-10 17:24:08 +02:00
# ifdef QT_RESIZE_DEBUG
2022-07-05 14:09:14 +06:00
qDebug ( ) < < " Resize " ;
2023-08-10 17:24:08 +02:00
# endif
2024-05-03 17:02:13 +02:00
w = static_cast < int > ( w / ( ! dpi_scale ? util : : screenOfWidget ( renderers [ monitor_index ] . get ( ) ) - > devicePixelRatio ( ) : 1. ) ) ;
2022-07-04 17:54:38 +06:00
2024-05-03 17:02:13 +02:00
int modifiedHeight = static_cast < int > ( h / ( ! dpi_scale ? util : : screenOfWidget ( renderers [ monitor_index ] . get ( ) ) - > devicePixelRatio ( ) : 1. ) ) ;
2022-07-04 17:54:38 +06:00
renderers [ monitor_index ] - > setFixedSize ( w , modifiedHeight ) ;
}
} ) ;
2021-12-29 23:49:09 +06:00
connect ( ui - > menubar , & QMenuBar : : triggered , this , [ this ] {
2021-11-25 10:20:56 +01:00
config_save ( ) ;
2022-11-19 08:49:04 -05:00
if ( QApplication : : activeWindow ( ) = = this ) {
2022-02-27 14:56:51 +02:00
ui - > stackedWidget - > setFocusRenderer ( ) ;
2021-12-29 23:49:09 +06:00
}
2021-11-25 10:20:56 +01:00
} ) ;
2021-11-30 22:06:41 +01:00
connect ( this , & MainWindow : : updateStatusBarPanes , this , [ this ] {
2021-12-14 00:31:55 +06:00
refreshMediaMenu ( ) ;
2021-11-30 22:06:41 +01:00
} ) ;
2021-12-03 11:38:00 +01:00
connect ( this , & MainWindow : : updateStatusBarPanes , this , & MainWindow : : refreshMediaMenu ) ;
2021-12-14 00:31:55 +06:00
connect ( this , & MainWindow : : updateStatusBarTip , status . get ( ) , & MachineStatus : : updateTip ) ;
2022-03-17 16:31:14 -03:00
connect ( this , & MainWindow : : statusBarMessage , status . get ( ) , & MachineStatus : : message , Qt : : QueuedConnection ) ;
2021-11-28 20:49:05 +01:00
2021-11-25 10:20:56 +01:00
ui - > actionKeyboard_requires_capture - > setChecked ( kbd_req_capture ) ;
ui - > actionRight_CTRL_is_left_ALT - > setChecked ( rctrl_is_lalt ) ;
2021-12-12 01:16:27 +06:00
ui - > actionResizable_window - > setChecked ( vid_resize = = 1 ) ;
ui - > actionRemember_size_and_position - > setChecked ( window_remember ) ;
2021-12-06 21:58:41 +01:00
ui - > menuWindow_scale_factor - > setEnabled ( vid_resize = = 0 ) ;
2021-12-12 01:16:27 +06:00
ui - > actionHiDPI_scaling - > setChecked ( dpi_scale ) ;
ui - > actionHide_status_bar - > setChecked ( hide_status_bar ) ;
2022-01-09 17:00:16 +02:00
ui - > actionHide_tool_bar - > setChecked ( hide_tool_bar ) ;
2022-07-10 11:41:02 +06:00
ui - > actionShow_non_primary_monitors - > setChecked ( show_second_monitors ) ;
2021-12-12 01:16:27 +06:00
ui - > actionUpdate_status_bar_icons - > setChecked ( update_icons ) ;
2022-01-09 01:04:59 +06:00
ui - > actionEnable_Discord_integration - > setChecked ( enable_discord ) ;
2022-08-10 01:27:54 +06:00
ui - > actionApply_fullscreen_stretch_mode_when_maximized - > setChecked ( video_fullscreen_scale_maximized ) ;
2021-12-24 16:31:36 +06:00
2023-02-01 17:17:56 +01:00
# ifndef DISCORD
ui - > actionEnable_Discord_integration - > setVisible ( false ) ;
2023-09-14 23:20:58 +05:00
# else
ui - > actionEnable_Discord_integration - > setEnabled ( discord_loaded ) ;
2023-02-01 17:17:56 +01:00
# endif
2022-03-11 12:03:54 +06:00
if ( ( QApplication : : platformName ( ) . contains ( " eglfs " ) | | QApplication : : platformName ( ) = = " haiku " ) ) {
2025-06-28 18:48:30 -04:00
if ( ( vid_api = = RENDERER_OPENGL3 ) | | ( vid_api = = RENDERER_VULKAN ) )
2022-11-19 08:49:04 -05:00
fprintf ( stderr , " OpenGL renderers are unsupported on %s. \n " , QApplication : : platformName ( ) . toUtf8 ( ) . data ( ) ) ;
2025-06-28 18:48:30 -04:00
vid_api = RENDERER_SOFTWARE ;
2022-04-21 16:32:46 +06:00
ui - > actionVulkan - > setVisible ( false ) ;
2022-03-11 12:03:54 +06:00
ui - > actionOpenGL_3_0_Core - > setVisible ( false ) ;
2021-12-24 16:31:36 +06:00
}
2022-02-27 14:56:51 +02:00
2022-08-03 13:05:21 +06:00
# ifndef USE_VNC
2025-06-28 18:48:30 -04:00
if ( vid_api = = RENDERER_VNC )
vid_api = RENDERER_SOFTWARE ;
2022-08-03 13:05:21 +06:00
ui - > actionVNC - > setVisible ( false ) ;
# endif
2022-11-03 21:58:54 +06:00
# if QT_CONFIG(vulkan)
bool vulkanAvailable = false ;
{
QVulkanInstance instance ;
instance . setApiVersion ( QVersionNumber ( 1 , 0 ) ) ;
if ( instance . create ( ) ) {
uint32_t physicalDevices = 0 ;
instance . functions ( ) - > vkEnumeratePhysicalDevices ( instance . vkInstance ( ) , & physicalDevices , nullptr ) ;
if ( physicalDevices ! = 0 ) {
vulkanAvailable = true ;
}
}
}
if ( ! vulkanAvailable )
2022-04-25 16:09:37 +06:00
# endif
2022-11-03 21:58:54 +06:00
{
2025-06-28 18:48:30 -04:00
if ( vid_api = = RENDERER_VULKAN )
vid_api = RENDERER_SOFTWARE ;
2022-11-03 21:58:54 +06:00
ui - > actionVulkan - > setVisible ( false ) ;
2021-12-06 21:39:39 +01:00
}
2022-04-25 16:09:37 +06:00
2024-05-03 17:02:13 +02:00
auto actGroup = new QActionGroup ( this ) ;
2021-12-18 01:03:05 +06:00
actGroup - > addAction ( ui - > actionSoftware_Renderer ) ;
2021-12-27 16:32:03 +06:00
actGroup - > addAction ( ui - > actionOpenGL_3_0_Core ) ;
2022-04-21 16:32:46 +06:00
actGroup - > addAction ( ui - > actionVulkan ) ;
2022-08-03 13:05:21 +06:00
actGroup - > addAction ( ui - > actionVNC ) ;
2022-02-27 14:56:51 +02:00
actGroup - > setExclusive ( true ) ;
2022-11-19 08:49:04 -05:00
connect ( actGroup , & QActionGroup : : triggered , [ this ] ( QAction * action ) {
2022-02-27 14:56:51 +02:00
vid_api = action - > property ( " vid_api " ) . toInt ( ) ;
2022-08-03 13:05:21 +06:00
# ifdef USE_VNC
2025-06-28 18:48:30 -04:00
if ( vnc_enabled & & vid_api ! = RENDERER_VNC ) {
2022-08-03 13:05:21 +06:00
startblit ( ) ;
vnc_enabled = 0 ;
vnc_close ( ) ;
video_setblit ( qt_blit ) ;
endblit ( ) ;
}
# endif
2022-07-05 00:21:30 +06:00
RendererStack : : Renderer newVidApi = RendererStack : : Renderer : : Software ;
2022-11-19 08:49:04 -05:00
switch ( vid_api ) {
2024-05-03 17:02:13 +02:00
default :
break ;
2025-06-28 18:48:30 -04:00
case RENDERER_SOFTWARE :
2022-08-03 13:05:21 +06:00
newVidApi = RendererStack : : Renderer : : Software ;
2022-11-19 08:49:04 -05:00
break ;
2025-06-28 18:48:30 -04:00
case RENDERER_OPENGL3 :
2023-05-29 01:30:51 -04:00
newVidApi = RendererStack : : Renderer : : OpenGL3 ;
2022-11-19 08:49:04 -05:00
break ;
2025-06-28 18:48:30 -04:00
case RENDERER_VULKAN :
2023-05-29 01:30:51 -04:00
newVidApi = RendererStack : : Renderer : : Vulkan ;
2022-11-19 08:49:04 -05:00
break ;
# ifdef USE_VNC
2025-06-28 18:48:30 -04:00
case RENDERER_VNC :
2022-11-19 08:49:04 -05:00
{
newVidApi = RendererStack : : Renderer : : Software ;
startblit ( ) ;
vnc_enabled = vnc_init ( nullptr ) ;
endblit ( ) ;
}
2022-08-03 13:05:21 +06:00
# endif
2022-02-27 14:56:51 +02:00
}
2022-07-05 00:21:30 +06:00
ui - > stackedWidget - > switchRenderer ( newVidApi ) ;
2025-08-27 02:24:59 +06:00
ui - > menuOpenGL_input_scale - > setEnabled ( newVidApi = = RendererStack : : Renderer : : OpenGL3 ) ;
ui - > menuOpenGL_input_stretch_mode - > setEnabled ( newVidApi = = RendererStack : : Renderer : : OpenGL3 ) ;
2022-11-19 08:49:04 -05:00
if ( ! show_second_monitors )
return ;
2022-07-05 00:21:30 +06:00
for ( int i = 1 ; i < MONITORS_NUM ; i + + ) {
2022-11-19 08:49:04 -05:00
if ( renderers [ i ] )
renderers [ i ] - > switchRenderer ( newVidApi ) ;
2022-07-05 00:21:30 +06:00
}
2022-02-27 14:56:51 +02:00
} ) ;
connect ( ui - > stackedWidget , & RendererStack : : rendererChanged , [ this ] ( ) {
2025-03-15 23:47:10 +06:00
ui - > actionRenderer_options - > setEnabled ( ui - > stackedWidget - > hasOptions ( ) ) ;
2022-02-27 14:56:51 +02:00
} ) ;
/* Trigger initial renderer switch */
2024-05-03 17:02:13 +02:00
for ( const auto action : actGroup - > actions ( ) )
2022-02-27 14:56:51 +02:00
if ( action - > property ( " vid_api " ) . toInt ( ) = = vid_api ) {
action - > setChecked ( true ) ;
emit actGroup - > triggered ( action ) ;
break ;
}
2025-08-27 02:24:59 +06:00
ui - > action_0_5x_2 - > setChecked ( video_gl_input_scale < 1.0 ) ;
ui - > action_1x_2 - > setChecked ( video_gl_input_scale > = 1.0 & & video_gl_input_scale < 1.5 ) ;
ui - > action1_5x_2 - > setChecked ( video_gl_input_scale > = 1.5 & & video_gl_input_scale < 2.0 ) ;
ui - > action_2x_2 - > setChecked ( video_gl_input_scale > = 2.0 & & video_gl_input_scale < 3.0 ) ;
ui - > action_3x_2 - > setChecked ( video_gl_input_scale > = 3.0 & & video_gl_input_scale < 4.0 ) ;
ui - > action_4x_2 - > setChecked ( video_gl_input_scale > = 4.0 & & video_gl_input_scale < 5.0 ) ;
ui - > action_5x_2 - > setChecked ( video_gl_input_scale > = 5.0 & & video_gl_input_scale < 6.0 ) ;
ui - > action_6x_2 - > setChecked ( video_gl_input_scale > = 6.0 & & video_gl_input_scale < 7.0 ) ;
ui - > action_7x_2 - > setChecked ( video_gl_input_scale > = 7.0 & & video_gl_input_scale < 8.0 ) ;
ui - > action_8x_2 - > setChecked ( video_gl_input_scale > = 8.0 ) ;
actGroup = new QActionGroup ( this ) ;
actGroup - > addAction ( ui - > action_0_5x_2 ) ;
actGroup - > addAction ( ui - > action_1x_2 ) ;
actGroup - > addAction ( ui - > action1_5x_2 ) ;
actGroup - > addAction ( ui - > action_2x_2 ) ;
actGroup - > addAction ( ui - > action_3x_2 ) ;
actGroup - > addAction ( ui - > action_4x_2 ) ;
actGroup - > addAction ( ui - > action_5x_2 ) ;
actGroup - > addAction ( ui - > action_6x_2 ) ;
actGroup - > addAction ( ui - > action_7x_2 ) ;
actGroup - > addAction ( ui - > action_8x_2 ) ;
connect ( actGroup , & QActionGroup : : triggered , this , [ this ] ( QAction * action ) {
if ( action = = ui - > action_0_5x_2 ) video_gl_input_scale = 0.5 ;
if ( action = = ui - > action_1x_2 ) video_gl_input_scale = 1 ;
if ( action = = ui - > action1_5x_2 ) video_gl_input_scale = 1.5 ;
if ( action = = ui - > action_2x_2 ) video_gl_input_scale = 2 ;
if ( action = = ui - > action_3x_2 ) video_gl_input_scale = 3 ;
if ( action = = ui - > action_4x_2 ) video_gl_input_scale = 4 ;
if ( action = = ui - > action_5x_2 ) video_gl_input_scale = 5 ;
if ( action = = ui - > action_6x_2 ) video_gl_input_scale = 6 ;
if ( action = = ui - > action_7x_2 ) video_gl_input_scale = 7 ;
if ( action = = ui - > action_8x_2 ) video_gl_input_scale = 8 ;
} ) ;
2021-12-06 21:58:41 +01:00
switch ( scale ) {
2024-05-03 17:02:13 +02:00
default :
break ;
2022-11-19 08:49:04 -05:00
case 0 :
ui - > action0_5x - > setChecked ( true ) ;
break ;
case 1 :
ui - > action1x - > setChecked ( true ) ;
break ;
case 2 :
ui - > action1_5x - > setChecked ( true ) ;
break ;
case 3 :
ui - > action2x - > setChecked ( true ) ;
break ;
case 4 :
ui - > action3x - > setChecked ( true ) ;
break ;
case 5 :
ui - > action4x - > setChecked ( true ) ;
break ;
case 6 :
ui - > action5x - > setChecked ( true ) ;
break ;
case 7 :
ui - > action6x - > setChecked ( true ) ;
break ;
case 8 :
ui - > action7x - > setChecked ( true ) ;
break ;
case 9 :
ui - > action8x - > setChecked ( true ) ;
break ;
2021-12-06 21:58:41 +01:00
}
2021-12-18 01:03:05 +06:00
actGroup = new QActionGroup ( this ) ;
actGroup - > addAction ( ui - > action0_5x ) ;
actGroup - > addAction ( ui - > action1x ) ;
actGroup - > addAction ( ui - > action1_5x ) ;
actGroup - > addAction ( ui - > action2x ) ;
2022-11-01 11:53:49 -07:00
actGroup - > addAction ( ui - > action3x ) ;
actGroup - > addAction ( ui - > action4x ) ;
actGroup - > addAction ( ui - > action5x ) ;
actGroup - > addAction ( ui - > action6x ) ;
actGroup - > addAction ( ui - > action7x ) ;
actGroup - > addAction ( ui - > action8x ) ;
2021-12-06 22:02:18 +01:00
switch ( video_filter_method ) {
2024-05-03 17:02:13 +02:00
default :
break ;
2022-11-19 08:49:04 -05:00
case 0 :
ui - > actionNearest - > setChecked ( true ) ;
break ;
case 1 :
ui - > actionLinear - > setChecked ( true ) ;
break ;
2021-12-06 22:02:18 +01:00
}
2021-12-18 01:03:05 +06:00
actGroup = new QActionGroup ( this ) ;
actGroup - > addAction ( ui - > actionNearest ) ;
actGroup - > addAction ( ui - > actionLinear ) ;
2021-12-07 13:47:42 +01:00
switch ( video_fullscreen_scale ) {
2024-05-03 17:02:13 +02:00
default :
break ;
2022-11-19 08:49:04 -05:00
case FULLSCR_SCALE_FULL :
ui - > actionFullScreen_stretch - > setChecked ( true ) ;
break ;
case FULLSCR_SCALE_43 :
ui - > actionFullScreen_43 - > setChecked ( true ) ;
break ;
case FULLSCR_SCALE_KEEPRATIO :
ui - > actionFullScreen_keepRatio - > setChecked ( true ) ;
break ;
case FULLSCR_SCALE_INT :
ui - > actionFullScreen_int - > setChecked ( true ) ;
break ;
2023-10-13 23:30:31 +02:00
case FULLSCR_SCALE_INT43 :
ui - > actionFullScreen_int43 - > setChecked ( true ) ;
break ;
2021-12-07 13:47:42 +01:00
}
2021-12-18 01:03:05 +06:00
actGroup = new QActionGroup ( this ) ;
actGroup - > addAction ( ui - > actionFullScreen_stretch ) ;
actGroup - > addAction ( ui - > actionFullScreen_43 ) ;
actGroup - > addAction ( ui - > actionFullScreen_keepRatio ) ;
actGroup - > addAction ( ui - > actionFullScreen_int ) ;
2023-10-14 23:42:02 +02:00
actGroup - > addAction ( ui - > actionFullScreen_int43 ) ;
2025-08-27 02:24:59 +06:00
switch ( video_gl_input_scale_mode ) {
default :
break ;
case FULLSCR_SCALE_FULL :
ui - > action_Full_screen_stretch_gl - > setChecked ( true ) ;
break ;
case FULLSCR_SCALE_43 :
ui - > action_4_3_gl - > setChecked ( true ) ;
break ;
case FULLSCR_SCALE_KEEPRATIO :
ui - > action_Square_pixels_keep_ratio_gl - > setChecked ( true ) ;
break ;
case FULLSCR_SCALE_INT :
ui - > action_Integer_scale_gl - > setChecked ( true ) ;
break ;
case FULLSCR_SCALE_INT43 :
ui - > action4_3_Integer_scale_gl - > setChecked ( true ) ;
break ;
}
actGroup = new QActionGroup ( this ) ;
actGroup - > addAction ( ui - > action_Full_screen_stretch_gl ) ;
actGroup - > addAction ( ui - > action_4_3_gl ) ;
actGroup - > addAction ( ui - > action_Square_pixels_keep_ratio_gl ) ;
actGroup - > addAction ( ui - > action_Integer_scale_gl ) ;
actGroup - > addAction ( ui - > action4_3_Integer_scale_gl ) ;
connect ( actGroup , & QActionGroup : : triggered , this , [ this ] ( QAction * action ) {
if ( action = = ui - > action_Full_screen_stretch_gl ) video_gl_input_scale_mode = FULLSCR_SCALE_FULL ;
if ( action = = ui - > action_4_3_gl ) video_gl_input_scale_mode = FULLSCR_SCALE_43 ;
if ( action = = ui - > action_Square_pixels_keep_ratio_gl ) video_gl_input_scale_mode = FULLSCR_SCALE_KEEPRATIO ;
if ( action = = ui - > action_Integer_scale_gl ) video_gl_input_scale_mode = FULLSCR_SCALE_INT ;
if ( action = = ui - > action4_3_Integer_scale_gl ) video_gl_input_scale_mode = FULLSCR_SCALE_INT43 ;
} ) ;
2021-12-08 15:12:21 +01:00
switch ( video_grayscale ) {
2024-05-03 17:02:13 +02:00
default :
break ;
2022-11-19 08:49:04 -05:00
case 0 :
ui - > actionRGB_Color - > setChecked ( true ) ;
break ;
case 1 :
ui - > actionRGB_Grayscale - > setChecked ( true ) ;
break ;
case 2 :
ui - > actionAmber_monitor - > setChecked ( true ) ;
break ;
case 3 :
ui - > actionGreen_monitor - > setChecked ( true ) ;
break ;
case 4 :
ui - > actionWhite_monitor - > setChecked ( true ) ;
break ;
2021-12-08 15:12:21 +01:00
}
2021-12-18 01:03:05 +06:00
actGroup = new QActionGroup ( this ) ;
actGroup - > addAction ( ui - > actionRGB_Grayscale ) ;
actGroup - > addAction ( ui - > actionAmber_monitor ) ;
actGroup - > addAction ( ui - > actionGreen_monitor ) ;
actGroup - > addAction ( ui - > actionWhite_monitor ) ;
actGroup - > addAction ( ui - > actionRGB_Color ) ;
2021-12-08 15:17:33 +01:00
switch ( video_graytype ) {
2024-05-03 17:02:13 +02:00
default :
break ;
2022-11-19 08:49:04 -05:00
case 0 :
ui - > actionBT601_NTSC_PAL - > setChecked ( true ) ;
break ;
case 1 :
ui - > actionBT709_HDTV - > setChecked ( true ) ;
break ;
case 2 :
ui - > actionAverage - > setChecked ( true ) ;
break ;
2021-12-08 15:17:33 +01:00
}
2021-12-18 01:03:05 +06:00
actGroup = new QActionGroup ( this ) ;
actGroup - > addAction ( ui - > actionBT601_NTSC_PAL ) ;
actGroup - > addAction ( ui - > actionBT709_HDTV ) ;
actGroup - > addAction ( ui - > actionAverage ) ;
2021-12-09 11:55:28 +01:00
if ( force_43 > 0 ) {
ui - > actionForce_4_3_display_ratio - > setChecked ( true ) ;
}
if ( enable_overscan > 0 ) {
ui - > actionCGA_PCjr_Tandy_EGA_S_VGA_overscan - > setChecked ( true ) ;
}
if ( vid_cga_contrast > 0 ) {
ui - > actionChange_contrast_for_monochrome_display - > setChecked ( true ) ;
}
2023-10-13 23:30:31 +02:00
if ( do_auto_pause > 0 ) {
ui - > actionAuto_pause - > setChecked ( true ) ;
}
2025-08-19 21:03:09 +02:00
if ( force_constant_mouse > 0 ) {
ui - > actionUpdate_mouse_every_CPU_frame - > setChecked ( true ) ;
}
2021-12-04 21:33:04 +01:00
2022-01-08 00:53:45 +06:00
# ifdef Q_OS_MACOS
ui - > actionCtrl_Alt_Del - > setShortcutVisibleInContextMenu ( true ) ;
ui - > actionTake_screenshot - > setShortcutVisibleInContextMenu ( true ) ;
# endif
2022-11-19 08:49:04 -05:00
if ( ! vnc_enabled )
video_setblit ( qt_blit ) ;
2022-02-04 15:19:18 +06:00
2023-11-11 15:42:15 +01:00
if ( start_in_fullscreen ) {
2024-02-13 18:40:07 +05:00
connect ( ui - > stackedWidget , & RendererStack : : blitToRenderer , this , [ this ] ( ) {
2023-11-11 14:02:56 +02:00
if ( start_in_fullscreen ) {
QTimer : : singleShot ( 100 , ui - > actionFullscreen , & QAction : : trigger ) ;
start_in_fullscreen = 0 ;
}
} ) ;
}
2022-02-04 15:19:18 +06:00
# ifdef MTR_ENABLED
{
2022-02-05 02:04:32 +06:00
ui - > actionBegin_trace - > setVisible ( true ) ;
ui - > actionEnd_trace - > setVisible ( true ) ;
ui - > actionBegin_trace - > setShortcut ( QKeySequence ( Qt : : Key_Control + Qt : : Key_T ) ) ;
ui - > actionEnd_trace - > setShortcut ( QKeySequence ( Qt : : Key_Control + Qt : : Key_T ) ) ;
ui - > actionEnd_trace - > setDisabled ( true ) ;
2022-11-19 08:49:04 -05:00
static auto init_trace = [ & ] {
2022-02-04 15:19:18 +06:00
mtr_init ( " trace.json " ) ;
mtr_start ( ) ;
} ;
2022-11-19 08:49:04 -05:00
static auto shutdown_trace = [ & ] {
2022-02-04 15:19:18 +06:00
mtr_stop ( ) ;
mtr_shutdown ( ) ;
} ;
2022-11-19 08:49:04 -05:00
# ifdef Q_OS_MACOS
2022-02-05 02:04:32 +06:00
ui - > actionBegin_trace - > setShortcutVisibleInContextMenu ( true ) ;
ui - > actionEnd_trace - > setShortcutVisibleInContextMenu ( true ) ;
2022-11-19 08:49:04 -05:00
# endif
2022-02-04 15:19:18 +06:00
static bool trace = false ;
2022-11-19 08:49:04 -05:00
connect ( ui - > actionBegin_trace , & QAction : : triggered , this , [ this ] {
if ( trace )
return ;
2022-02-05 02:04:32 +06:00
ui - > actionBegin_trace - > setDisabled ( true ) ;
ui - > actionEnd_trace - > setDisabled ( false ) ;
2022-02-04 15:19:18 +06:00
init_trace ( ) ;
trace = true ;
} ) ;
2022-11-19 08:49:04 -05:00
connect ( ui - > actionEnd_trace , & QAction : : triggered , this , [ this ] {
if ( ! trace )
return ;
2022-02-05 02:04:32 +06:00
ui - > actionBegin_trace - > setDisabled ( false ) ;
ui - > actionEnd_trace - > setDisabled ( true ) ;
2022-02-04 15:19:18 +06:00
shutdown_trace ( ) ;
trace = false ;
} ) ;
}
# endif
2022-02-09 00:47:05 +06:00
2022-02-10 00:50:37 +06:00
setContextMenuPolicy ( Qt : : PreventContextMenu ) ;
2023-07-24 15:05:29 -03:00
/* Remove default Shift+F10 handler, which unfocuses keyboard input even with no context menu. */
2025-08-15 00:31:57 +05:00
# if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
connect ( new QShortcut ( QKeySequence ( Qt : : SHIFT | Qt : : Key_F10 ) , this ) , & QShortcut : : activated , this , [ ] ( ) { } ) ;
# else
2023-08-08 15:38:40 +02:00
connect ( new QShortcut ( QKeySequence ( Qt : : SHIFT + Qt : : Key_F10 ) , this ) , & QShortcut : : activated , this , [ ] ( ) { } ) ;
2025-08-15 00:31:57 +05:00
# endif
2022-07-04 01:50:42 +06:00
connect ( this , & MainWindow : : initRendererMonitor , this , & MainWindow : : initRendererMonitorSlot ) ;
connect ( this , & MainWindow : : initRendererMonitorForNonQtThread , this , & MainWindow : : initRendererMonitorSlot , Qt : : BlockingQueuedConnection ) ;
connect ( this , & MainWindow : : destroyRendererMonitor , this , & MainWindow : : destroyRendererMonitorSlot ) ;
connect ( this , & MainWindow : : destroyRendererMonitorForNonQtThread , this , & MainWindow : : destroyRendererMonitorSlot , Qt : : BlockingQueuedConnection ) ;
2022-07-30 00:09:09 +06:00
# ifdef Q_OS_MACOS
2022-11-19 08:49:04 -05:00
QTimer : : singleShot ( 0 , this , [ this ] ( ) {
for ( auto curObj : this - > menuBar ( ) - > children ( ) ) {
if ( qobject_cast < QMenu * > ( curObj ) ) {
auto menu = qobject_cast < QMenu * > ( curObj ) ;
menu - > setSeparatorsCollapsible ( false ) ;
for ( auto curObj2 : menu - > children ( ) ) {
if ( qobject_cast < QMenu * > ( curObj2 ) ) {
auto menu2 = qobject_cast < QMenu * > ( curObj2 ) ;
menu2 - > setSeparatorsCollapsible ( false ) ;
}
}
}
}
} ) ;
2022-07-30 00:09:09 +06:00
# endif
2023-01-03 15:42:57 +06:00
2025-04-05 23:59:49 +06:00
QTimer : : singleShot ( 0 , this , [ this ] ( ) {
for ( auto curObj : this - > menuBar ( ) - > children ( ) ) {
if ( qobject_cast < QMenu * > ( curObj ) ) {
auto menu = qobject_cast < QMenu * > ( curObj ) ;
for ( auto curObj2 : menu - > children ( ) ) {
if ( qobject_cast < QAction * > ( curObj2 ) ) {
auto action = qobject_cast < QAction * > ( curObj2 ) ;
if ( ! action - > shortcut ( ) . isEmpty ( ) ) {
this - > insertAction ( nullptr , action ) ;
}
}
}
}
}
} ) ;
2023-01-03 15:42:57 +06:00
actGroup = new QActionGroup ( this ) ;
actGroup - > addAction ( ui - > actionCursor_Puck ) ;
actGroup - > addAction ( ui - > actionPen ) ;
if ( tablet_tool_type = = 1 ) {
ui - > actionPen - > setChecked ( true ) ;
} else {
ui - > actionCursor_Puck - > setChecked ( true ) ;
}
2023-04-07 22:33:53 -03:00
2023-04-08 00:31:25 -03:00
# ifdef XKBCOMMON
# ifdef XKBCOMMON_X11
2023-04-07 22:33:53 -03:00
if ( QApplication : : platformName ( ) . contains ( " xcb " ) )
xkbcommon_x11_init ( ) ;
2023-04-08 00:31:25 -03:00
else
# endif
# ifdef WAYLAND
if ( QApplication : : platformName ( ) . contains ( " wayland " ) )
xkbcommon_wl_init ( ) ;
else
# endif
{ }
2023-04-07 22:33:53 -03:00
# endif
2023-11-21 23:37:50 +01:00
2023-11-22 08:22:46 +01:00
# if defined Q_OS_UNIX && !defined Q_OS_MACOS && !defined Q_OS_HAIKU
2023-11-21 23:37:50 +01:00
if ( QApplication : : platformName ( ) . contains ( " xcb " ) ) {
QTimer : : singleShot ( 0 , this , [ this ] {
auto whandle = windowHandle ( ) ;
if ( ! whandle ) {
qWarning ( ) < < " No window handle " ;
} else {
QPlatformWindow * window = whandle - > handle ( ) ;
set_wm_class ( window - > winId ( ) , vm_name ) ;
}
} ) ;
}
# endif
2025-04-19 19:44:47 -07:00
updateShortcuts ( ) ;
2021-11-25 10:20:56 +01:00
}
2022-11-19 08:49:04 -05:00
void
MainWindow : : closeEvent ( QCloseEvent * event )
{
2022-03-10 23:14:13 +02:00
if ( mouse_capture ) {
event - > ignore ( ) ;
return ;
}
2022-11-19 08:49:04 -05:00
if ( confirm_exit & & confirm_exit_cmdl & & cpu_thread_run ) {
2022-01-07 16:21:40 +06:00
QMessageBox questionbox ( QMessageBox : : Icon : : Question , " 86Box " , tr ( " Are you sure you want to exit 86Box? " ) , QMessageBox : : Yes | QMessageBox : : No , this ) ;
2024-05-03 17:02:13 +02:00
auto chkbox = new QCheckBox ( tr ( " Don't show this message again " ) ) ;
2021-12-12 01:16:27 +06:00
questionbox . setCheckBox ( chkbox ) ;
chkbox - > setChecked ( ! confirm_exit ) ;
2022-02-27 14:56:51 +02:00
2021-12-12 01:16:27 +06:00
QObject : : connect ( chkbox , & QCheckBox : : stateChanged , [ ] ( int state ) {
confirm_exit = ( state = = Qt : : CheckState : : Unchecked ) ;
} ) ;
questionbox . exec ( ) ;
if ( questionbox . result ( ) = = QMessageBox : : No ) {
confirm_exit = true ;
event - > ignore ( ) ;
return ;
}
}
if ( window_remember ) {
window_w = ui - > stackedWidget - > width ( ) ;
window_h = ui - > stackedWidget - > height ( ) ;
if ( ! QApplication : : platformName ( ) . contains ( " wayland " ) ) {
window_x = this - > geometry ( ) . x ( ) ;
window_y = this - > geometry ( ) . y ( ) ;
}
2022-07-05 16:40:04 +06:00
for ( int i = 1 ; i < MONITORS_NUM ; i + + ) {
if ( renderers [ i ] ) {
monitor_settings [ i ] . mon_window_w = renderers [ i ] - > geometry ( ) . width ( ) ;
monitor_settings [ i ] . mon_window_h = renderers [ i ] - > geometry ( ) . height ( ) ;
2022-11-19 08:49:04 -05:00
if ( QApplication : : platformName ( ) . contains ( " wayland " ) )
continue ;
2022-07-05 16:40:04 +06:00
monitor_settings [ i ] . mon_window_x = renderers [ i ] - > geometry ( ) . x ( ) ;
monitor_settings [ i ] . mon_window_y = renderers [ i ] - > geometry ( ) . y ( ) ;
}
}
2021-12-12 01:16:27 +06:00
}
2022-04-21 16:32:48 +06:00
2022-04-21 13:56:39 -03:00
if ( ui - > stackedWidget - > mouse_exit_func )
ui - > stackedWidget - > mouse_exit_func ( ) ;
2022-04-21 16:32:48 +06:00
2022-04-24 00:58:08 +06:00
ui - > stackedWidget - > switchRenderer ( RendererStack : : Renderer : : Software ) ;
2025-03-10 21:22:52 +06:00
for ( int i = 1 ; i < MONITORS_NUM ; i + + ) {
if ( renderers [ i ] & & renderers [ i ] - > isHidden ( ) ) {
renderers [ i ] - > show ( ) ;
QApplication : : processEvents ( ) ;
renderers [ i ] - > switchRenderer ( RendererStack : : Renderer : : Software ) ;
QApplication : : processEvents ( ) ;
}
}
2022-07-05 16:40:04 +06:00
2022-02-12 17:31:28 +02:00
qt_nvr_save ( ) ;
2021-12-24 01:57:26 +06:00
config_save ( ) ;
2022-05-04 13:13:03 +06:00
QApplication : : processEvents ( ) ;
2022-07-05 16:40:04 +06:00
cpu_thread_run = 0 ;
2021-12-12 01:16:27 +06:00
event - > accept ( ) ;
}
2025-04-19 19:44:47 -07:00
void MainWindow : : updateShortcuts ( )
{
2025-04-20 14:28:10 -07:00
/*
Update menu shortcuts from accelerator table
2025-04-20 15:23:38 -07:00
Note that these only work in windowed mode . If you add any new shortcuts ,
you have to go duplicate them in MainWindow : : eventFilter ( )
2025-04-20 14:28:10 -07:00
*/
2025-04-19 19:44:47 -07:00
2025-04-20 13:43:14 -07:00
// First we need to wipe all existing accelerators, otherwise Qt will
// run into conflicts with old ones.
2025-04-19 19:44:47 -07:00
ui - > actionTake_screenshot - > setShortcut ( QKeySequence ( ) ) ;
ui - > actionCtrl_Alt_Del - > setShortcut ( QKeySequence ( ) ) ;
ui - > actionCtrl_Alt_Esc - > setShortcut ( QKeySequence ( ) ) ;
ui - > actionHard_Reset - > setShortcut ( QKeySequence ( ) ) ;
2025-04-20 14:28:10 -07:00
ui - > actionPause - > setShortcut ( QKeySequence ( ) ) ;
2025-04-20 14:31:46 -07:00
ui - > actionMute_Unmute - > setShortcut ( QKeySequence ( ) ) ;
2025-04-19 19:44:47 -07:00
int accID ;
QKeySequence seq ;
accID = FindAccelerator ( " screenshot " ) ;
seq = QKeySequence : : fromString ( acc_keys [ accID ] . seq ) ;
ui - > actionTake_screenshot - > setShortcut ( seq ) ;
accID = FindAccelerator ( " send_ctrl_alt_del " ) ;
seq = QKeySequence : : fromString ( acc_keys [ accID ] . seq ) ;
ui - > actionCtrl_Alt_Del - > setShortcut ( seq ) ;
accID = FindAccelerator ( " send_ctrl_alt_esc " ) ;
seq = QKeySequence : : fromString ( acc_keys [ accID ] . seq ) ;
ui - > actionCtrl_Alt_Esc - > setShortcut ( seq ) ;
accID = FindAccelerator ( " hard_reset " ) ;
seq = QKeySequence : : fromString ( acc_keys [ accID ] . seq ) ;
ui - > actionHard_Reset - > setShortcut ( seq ) ;
2025-04-20 13:43:14 -07:00
accID = FindAccelerator ( " fullscreen " ) ;
2025-04-19 19:44:47 -07:00
seq = QKeySequence : : fromString ( acc_keys [ accID ] . seq ) ;
2025-04-20 13:43:14 -07:00
ui - > actionFullscreen - > setShortcut ( seq ) ;
2025-04-20 14:28:10 -07:00
accID = FindAccelerator ( " pause " ) ;
seq = QKeySequence : : fromString ( acc_keys [ accID ] . seq ) ;
ui - > actionPause - > setShortcut ( seq ) ;
2025-04-20 14:31:46 -07:00
accID = FindAccelerator ( " mute " ) ;
seq = QKeySequence : : fromString ( acc_keys [ accID ] . seq ) ;
ui - > actionMute_Unmute - > setShortcut ( seq ) ;
2025-04-19 19:44:47 -07:00
}
2025-03-26 02:08:12 +06:00
void
MainWindow : : resizeEvent ( QResizeEvent * event )
{
//qDebug() << pos().x() + event->size().width();
//qDebug() << pos().y() + event->size().height();
2025-04-02 00:33:24 +06:00
if ( vid_resize = = 1 | | video_fullscreen )
2025-03-26 02:08:12 +06:00
return ;
int newX = pos ( ) . x ( ) ;
int newY = pos ( ) . y ( ) ;
if ( ( ( frameGeometry ( ) . x ( ) + event - > size ( ) . width ( ) + 1 ) > util : : screenOfWidget ( this ) - > availableGeometry ( ) . right ( ) ) ) {
//move(util::screenOfWidget(this)->availableGeometry().right() - size().width() - 1, pos().y());
newX = util : : screenOfWidget ( this ) - > availableGeometry ( ) . right ( ) - frameGeometry ( ) . width ( ) - 1 ;
if ( newX < 1 ) newX = 1 ;
}
if ( ( ( frameGeometry ( ) . y ( ) + event - > size ( ) . height ( ) + 1 ) > util : : screenOfWidget ( this ) - > availableGeometry ( ) . bottom ( ) ) ) {
newY = util : : screenOfWidget ( this ) - > availableGeometry ( ) . bottom ( ) - frameGeometry ( ) . height ( ) - 1 ;
if ( newY < 1 ) newY = 1 ;
}
move ( newX , newY ) ;
}
2022-11-19 08:49:04 -05:00
void
MainWindow : : initRendererMonitorSlot ( int monitor_index )
2022-07-04 01:50:42 +06:00
{
2022-11-19 08:49:04 -05:00
auto & secondaryRenderer = this - > renderers [ monitor_index ] ;
2024-05-03 17:02:13 +02:00
secondaryRenderer = std : : make_unique < RendererStack > ( nullptr , monitor_index ) ;
2022-07-04 01:50:42 +06:00
if ( secondaryRenderer ) {
2022-11-19 08:49:04 -05:00
connect ( secondaryRenderer . get ( ) , & RendererStack : : rendererChanged , this , [ this , monitor_index ] {
2022-07-04 01:50:42 +06:00
this - > renderers [ monitor_index ] - > show ( ) ;
} ) ;
2022-07-05 17:57:25 +06:00
secondaryRenderer - > setWindowFlags ( Qt : : CustomizeWindowHint | Qt : : WindowTitleHint | Qt : : WindowCloseButtonHint ) ;
2022-07-04 01:50:42 +06:00
secondaryRenderer - > setWindowTitle ( QObject : : tr ( " 86Box Monitor # " ) + QString : : number ( monitor_index + 1 ) ) ;
2025-04-05 23:59:49 +06:00
secondaryRenderer - > setContextMenuPolicy ( Qt : : PreventContextMenu ) ;
for ( int i = 0 ; i < this - > actions ( ) . size ( ) ; i + + ) {
secondaryRenderer - > addAction ( this - > actions ( ) [ i ] ) ;
}
2022-07-05 16:40:04 +06:00
2024-05-03 17:02:13 +02:00
if ( vid_resize = = 2 )
2022-07-04 01:50:42 +06:00
secondaryRenderer - > setFixedSize ( fixed_size_x , fixed_size_y ) ;
secondaryRenderer - > setWindowIcon ( this - > windowIcon ( ) ) ;
2025-03-06 22:20:13 +05:00
# ifdef Q_OS_WINDOWS
2025-03-07 00:11:45 +05:00
util : : setWin11RoundedCorners ( secondaryRenderer - > winId ( ) , false ) ;
2025-03-06 22:20:13 +05:00
# endif
2022-07-10 11:41:02 +06:00
if ( show_second_monitors ) {
secondaryRenderer - > show ( ) ;
if ( window_remember ) {
secondaryRenderer - > setGeometry ( monitor_settings [ monitor_index ] . mon_window_x < 120 ? 120 : monitor_settings [ monitor_index ] . mon_window_x ,
2022-11-19 08:49:04 -05:00
monitor_settings [ monitor_index ] . mon_window_y < 120 ? 120 : monitor_settings [ monitor_index ] . mon_window_y ,
monitor_settings [ monitor_index ] . mon_window_w > 2048 ? 2048 : monitor_settings [ monitor_index ] . mon_window_w ,
monitor_settings [ monitor_index ] . mon_window_h > 2048 ? 2048 : monitor_settings [ monitor_index ] . mon_window_h ) ;
2022-07-10 11:41:02 +06:00
}
2024-05-03 17:02:13 +02:00
if ( monitor_settings [ monitor_index ] . mon_window_maximized )
2022-08-14 12:28:36 +06:00
secondaryRenderer - > showMaximized ( ) ;
2022-11-19 08:49:04 -05:00
secondaryRenderer - > switchRenderer ( ( RendererStack : : Renderer ) vid_api ) ;
2023-03-04 23:10:43 +06:00
secondaryRenderer - > setMouseTracking ( true ) ;
2024-01-15 03:16:22 +01:00
if ( monitor_settings [ monitor_index ] . mon_window_maximized ) {
if ( renderers [ monitor_index ] )
renderers [ monitor_index ] - > onResize ( renderers [ monitor_index ] - > width ( ) ,
renderers [ monitor_index ] - > height ( ) ) ;
device_force_redraw ( ) ;
}
2022-07-10 11:41:02 +06:00
}
2022-07-04 01:50:42 +06:00
}
}
2022-11-19 08:49:04 -05:00
void
MainWindow : : destroyRendererMonitorSlot ( int monitor_index )
2022-07-04 01:50:42 +06:00
{
if ( this - > renderers [ monitor_index ] ) {
2022-07-05 14:09:14 +06:00
if ( window_remember ) {
monitor_settings [ monitor_index ] . mon_window_w = renderers [ monitor_index ] - > geometry ( ) . width ( ) ;
monitor_settings [ monitor_index ] . mon_window_h = renderers [ monitor_index ] - > geometry ( ) . height ( ) ;
monitor_settings [ monitor_index ] . mon_window_x = renderers [ monitor_index ] - > geometry ( ) . x ( ) ;
monitor_settings [ monitor_index ] . mon_window_y = renderers [ monitor_index ] - > geometry ( ) . y ( ) ;
}
config_save ( ) ;
2022-07-04 01:50:42 +06:00
this - > renderers [ monitor_index ] . release ( ) - > deleteLater ( ) ;
2023-01-26 14:29:40 +06:00
ui - > stackedWidget - > switchRenderer ( ( RendererStack : : Renderer ) vid_api ) ;
2022-07-04 01:50:42 +06:00
}
}
2022-11-19 08:49:04 -05:00
MainWindow : : ~ MainWindow ( )
{
2021-11-25 10:20:56 +01:00
delete ui ;
}
2022-11-19 08:49:04 -05:00
void
MainWindow : : showEvent ( QShowEvent * event )
{
if ( shownonce )
return ;
2021-12-24 01:57:26 +06:00
shownonce = true ;
2022-08-01 17:36:46 +06:00
if ( window_remember ) {
2022-11-19 08:49:04 -05:00
if ( window_w = = 0 )
window_w = 320 ;
if ( window_h = = 0 )
window_h = 200 ;
2022-08-01 17:36:46 +06:00
}
2021-12-12 01:16:27 +06:00
if ( window_remember & & ! QApplication : : platformName ( ) . contains ( " wayland " ) ) {
2022-02-09 16:45:57 +06:00
setGeometry ( window_x , window_y , window_w , window_h + menuBar ( ) - > height ( ) + ( hide_status_bar ? 0 : statusBar ( ) - > height ( ) ) + ( hide_tool_bar ? 0 : ui - > toolBar - > height ( ) ) ) ;
2021-12-12 01:16:27 +06:00
}
if ( vid_resize = = 2 ) {
2022-11-19 08:49:04 -05:00
setFixedSize ( fixed_size_x , fixed_size_y + menuBar ( ) - > height ( ) + ( hide_status_bar ? 0 : statusBar ( ) - > height ( ) ) + ( hide_tool_bar ? 0 : ui - > toolBar - > height ( ) ) ) ;
2022-01-09 17:00:16 +02:00
2022-07-04 01:50:42 +06:00
monitors [ 0 ] . mon_scrnsz_x = fixed_size_x ;
monitors [ 0 ] . mon_scrnsz_y = fixed_size_y ;
2021-12-12 01:16:27 +06:00
}
2022-07-11 20:52:04 +06:00
if ( window_remember & & vid_resize = = 1 ) {
2022-02-11 15:40:07 +06:00
ui - > stackedWidget - > setFixedSize ( window_w , window_h ) ;
2025-08-15 17:43:11 +02:00
# ifndef Q_OS_MACOS
2022-07-12 17:28:05 +06:00
QApplication : : processEvents ( ) ;
2025-08-15 17:43:11 +02:00
# endif
2022-07-12 17:28:05 +06:00
this - > adjustSize ( ) ;
2022-07-11 20:52:04 +06:00
}
2021-12-12 01:16:27 +06:00
}
2022-11-19 08:49:04 -05:00
void
MainWindow : : on_actionKeyboard_requires_capture_triggered ( )
{
2021-11-25 10:20:56 +01:00
kbd_req_capture ^ = 1 ;
2025-08-01 02:31:29 +05:00
# ifndef Q_OS_MACOS
qt_set_sequence_auto_mnemonic ( ! ! kbd_req_capture ) ;
/* Hack to get the menubar to update the internal Alt+shortcut table */
if ( ! video_fullscreen ) {
ui - > menubar - > hide ( ) ;
ui - > menubar - > show ( ) ;
}
# endif
2021-11-25 10:20:56 +01:00
}
2022-11-19 08:49:04 -05:00
void
MainWindow : : on_actionRight_CTRL_is_left_ALT_triggered ( )
{
2021-11-25 10:20:56 +01:00
rctrl_is_lalt ^ = 1 ;
}
2022-11-19 08:49:04 -05:00
void
MainWindow : : on_actionHard_Reset_triggered ( )
{
if ( confirm_reset ) {
2022-01-07 16:41:57 +06:00
QMessageBox questionbox ( QMessageBox : : Icon : : Question , " 86Box " , tr ( " Are you sure you want to hard reset the emulated machine? " ) , QMessageBox : : NoButton , this ) ;
2022-07-11 03:26:55 +02:00
questionbox . addButton ( tr ( " Reset " ) , QMessageBox : : AcceptRole ) ;
questionbox . addButton ( tr ( " Don't reset " ) , QMessageBox : : RejectRole ) ;
2024-05-03 17:02:13 +02:00
const auto chkbox = new QCheckBox ( tr ( " Don't show this message again " ) ) ;
2022-01-07 16:41:57 +06:00
questionbox . setCheckBox ( chkbox ) ;
chkbox - > setChecked ( ! confirm_reset ) ;
2022-02-27 14:56:51 +02:00
2022-01-07 16:41:57 +06:00
QObject : : connect ( chkbox , & QCheckBox : : stateChanged , [ ] ( int state ) {
confirm_reset = ( state = = Qt : : CheckState : : Unchecked ) ;
} ) ;
questionbox . exec ( ) ;
2022-11-19 08:49:04 -05:00
if ( questionbox . result ( ) = = QDialog : : Accepted ) {
2022-01-07 16:41:57 +06:00
confirm_reset = true ;
return ;
}
}
config_changed = 2 ;
2021-11-25 10:20:56 +01:00
pc_reset_hard ( ) ;
}
2022-11-19 08:49:04 -05:00
void
MainWindow : : on_actionCtrl_Alt_Del_triggered ( )
{
2021-11-25 10:20:56 +01:00
pc_send_cad ( ) ;
}
2022-11-19 08:49:04 -05:00
void
MainWindow : : on_actionCtrl_Alt_Esc_triggered ( )
{
2021-11-25 10:20:56 +01:00
pc_send_cae ( ) ;
}
2022-11-19 08:49:04 -05:00
void
MainWindow : : on_actionPause_triggered ( )
{
2021-11-25 10:20:56 +01:00
plat_pause ( dopause ^ 1 ) ;
}
2022-11-19 08:49:04 -05:00
void
MainWindow : : on_actionExit_triggered ( )
{
2021-11-25 10:20:56 +01:00
close ( ) ;
}
2022-11-19 08:49:04 -05:00
void
MainWindow : : on_actionSettings_triggered ( )
{
2024-05-03 17:02:13 +02:00
const int currentPause = dopause ;
2021-12-01 14:50:49 +06:00
plat_pause ( 1 ) ;
Settings settings ( this ) ;
settings . setModal ( true ) ;
settings . setWindowModality ( Qt : : WindowModal ) ;
2023-08-07 18:49:58 +02:00
settings . setWindowFlag ( Qt : : CustomizeWindowHint , true ) ;
settings . setWindowFlag ( Qt : : WindowTitleHint , true ) ;
settings . setWindowFlag ( Qt : : WindowSystemMenuHint , false ) ;
2021-11-25 10:20:56 +01:00
settings . exec ( ) ;
switch ( settings . result ( ) ) {
2024-05-03 17:02:13 +02:00
default :
break ;
2022-11-19 08:49:04 -05:00
case QDialog : : Accepted :
settings . save ( ) ;
config_changed = 2 ;
2025-08-02 00:34:53 +05:00
updateShortcuts ( ) ;
emit vmmConfigurationChanged ( ) ;
2024-08-24 04:24:06 +02:00
pc_reset_hard ( ) ;
2022-11-19 08:49:04 -05:00
break ;
case QDialog : : Rejected :
break ;
2021-11-25 10:20:56 +01:00
}
2021-12-01 14:50:49 +06:00
plat_pause ( currentPause ) ;
2021-11-25 10:20:56 +01:00
}
2023-04-09 19:26:56 -03:00
void
MainWindow : : processKeyboardInput ( bool down , uint32_t keycode )
2021-11-30 16:26:49 +06:00
{
2023-04-09 19:26:56 -03:00
# if defined(Q_OS_WINDOWS) /* non-raw input */
keycode & = 0xffff ;
2022-03-19 23:06:17 +00:00
# elif defined(Q_OS_MACOS)
2023-04-09 19:26:56 -03:00
keycode = ( keycode < 127 ) ? cocoa_keycodes [ keycode ] : 0 ;
2022-03-11 12:03:54 +06:00
# elif defined(__HAIKU__)
2023-04-09 19:26:56 -03:00
keycode = be_keycodes [ keycode ] ;
2021-11-30 16:26:49 +06:00
# else
2023-04-07 22:33:53 -03:00
# ifdef XKBCOMMON
2023-04-08 18:58:26 -03:00
if ( xkbcommon_keymap )
2023-04-09 19:26:56 -03:00
keycode = xkbcommon_translate ( keycode ) ;
2023-04-08 18:58:26 -03:00
else
2023-04-08 17:58:55 -03:00
# endif
# ifdef EVDEV_KEYBOARD_HPP
2023-04-09 19:26:56 -03:00
keycode = evdev_translate ( keycode - 8 ) ;
2023-04-08 18:58:26 -03:00
# else
2023-04-09 19:26:56 -03:00
keycode = 0 ;
2023-04-07 22:33:53 -03:00
# endif
2021-11-30 16:26:49 +06:00
# endif
2023-04-09 19:26:56 -03:00
/* Apply special cases. */
switch ( keycode ) {
2024-05-03 17:02:13 +02:00
default :
break ;
2023-04-09 19:49:25 -03:00
case 0x54 : /* Alt + Print Screen (special case, i.e. evdev SELECTIVE_SCREENSHOT) */
/* Send Alt as well. */
if ( down ) {
keyboard_input ( down , 0x38 ) ;
} else {
keyboard_input ( down , keycode ) ;
keycode = 0x38 ;
}
break ;
2023-06-26 21:27:37 -03:00
case 0x80 . . . 0xff : /* regular break codes */
2023-04-11 11:58:11 -03:00
case 0x10b : /* Microsoft scroll up normal */
2023-06-26 21:27:37 -03:00
case 0x180 . . . 0x1ff : /* E0 break codes (including Microsoft scroll down normal) */
/* This key uses a break code as make. Send it manually, only on press. */
2024-08-07 23:21:58 +02:00
if ( down & & ( mouse_capture | | ! kbd_req_capture | | video_fullscreen ) ) {
2023-06-26 21:27:37 -03:00
if ( keycode & 0x100 )
keyboard_send ( 0xe0 ) ;
2023-04-11 11:58:11 -03:00
keyboard_send ( keycode & 0xff ) ;
}
return ;
2021-11-30 16:26:49 +06:00
2023-04-09 19:26:56 -03:00
case 0x11d : /* Right Ctrl */
if ( rctrl_is_lalt )
keycode = 0x38 ; /* map to Left Alt */
break ;
case 0x137 : /* Print Screen */
2024-08-07 23:21:58 +02:00
if ( keyboard_recv_ui ( 0x38 ) | | keyboard_recv_ui ( 0x138 ) ) { /* Alt+ */
2023-04-09 19:26:56 -03:00
keycode = 0x54 ;
} else if ( down ) {
keyboard_input ( down , 0x12a ) ;
} else {
keyboard_input ( down , keycode ) ;
keycode = 0x12a ;
}
break ;
case 0x145 : /* Pause */
2024-08-07 23:21:58 +02:00
if ( keyboard_recv_ui ( 0x1d ) | | keyboard_recv_ui ( 0x11d ) ) { /* Ctrl+ */
2023-04-09 19:26:56 -03:00
keycode = 0x146 ;
} else {
keyboard_input ( down , 0xe11d ) ;
keycode & = 0x00ff ;
}
break ;
}
2021-11-30 16:26:49 +06:00
2023-04-09 19:26:56 -03:00
keyboard_input ( down , keycode ) ;
2021-11-30 16:26:49 +06:00
}
2021-11-25 10:20:56 +01:00
2022-03-19 23:06:17 +00:00
# ifdef Q_OS_MACOS
// These modifiers are listed as "device-dependent" in IOLLEvent.h, but
// that's followed up with "(really?)". It's the only way to distinguish
// left and right modifiers with Qt 6 on macOS, so let's just roll with it.
static std : : unordered_map < uint32_t , uint16_t > mac_modifiers_to_xt = {
2022-11-19 08:49:04 -05:00
{ NX_DEVICELCTLKEYMASK , 0x1D } ,
{ NX_DEVICELSHIFTKEYMASK , 0x2A } ,
{ NX_DEVICERSHIFTKEYMASK , 0x36 } ,
{ NX_DEVICELCMDKEYMASK , 0x15B } ,
{ NX_DEVICERCMDKEYMASK , 0x15C } ,
{ NX_DEVICELALTKEYMASK , 0x38 } ,
{ NX_DEVICERALTKEYMASK , 0x138 } ,
{ NX_DEVICE_ALPHASHIFT_STATELESS_MASK , 0x3A } ,
{ NX_DEVICERCTLKEYMASK , 0x11D } ,
2021-12-05 20:51:59 +01:00
} ;
2023-04-10 12:57:42 -03:00
static bool mac_iso_swap = false ;
2021-12-05 20:51:59 +01:00
2022-11-19 08:49:04 -05:00
void
MainWindow : : processMacKeyboardInput ( bool down , const QKeyEvent * event )
2021-11-30 16:26:49 +06:00
{
2022-03-19 23:06:17 +00:00
// Per QTBUG-69608 (https://bugreports.qt.io/browse/QTBUG-69608),
// QKeyEvents QKeyEvents for presses/releases of modifiers on macOS give
// nativeVirtualKey() == 0 (at least in Qt 6). Handle this by manually
// processing the nativeModifiers(). We need to check whether the key() is
// a known modifier because because kVK_ANSI_A is also 0, so the
// nativeVirtualKey() == 0 condition is ambiguous...
if ( event - > nativeVirtualKey ( ) = = 0
& & ( event - > key ( ) = = Qt : : Key_Shift
| | event - > key ( ) = = Qt : : Key_Control
| | event - > key ( ) = = Qt : : Key_Meta
| | event - > key ( ) = = Qt : : Key_Alt
| | event - > key ( ) = = Qt : : Key_AltGr
| | event - > key ( ) = = Qt : : Key_CapsLock ) ) {
// We only process one modifier at a time since events from Qt seem to
// always be non-coalesced (NX_NONCOALESCEDMASK is always set).
uint32_t changed_modifiers = last_modifiers ^ event - > nativeModifiers ( ) ;
2022-11-19 08:49:04 -05:00
for ( auto const & pair : mac_modifiers_to_xt ) {
2022-03-19 23:06:17 +00:00
if ( changed_modifiers & pair . first ) {
last_modifiers ^ = pair . first ;
keyboard_input ( down , pair . second ) ;
return ;
}
2021-11-30 16:26:49 +06:00
}
2022-03-19 23:06:17 +00:00
// Caps Lock seems to be delivered as a single key press event when
// enabled and a single key release event when disabled, so we can't
// detect Caps Lock being held down; just send an infinitesimally-long
// press and release as a compromise.
//
// The event also doesn't get delivered if you turn Caps Lock off after
// turning it on when the window isn't focused. Doing better than this
// probably requires bypassing Qt input processing.
//
// It's possible that other lock keys get delivered in this way, but
// standard Apple keyboards don't have them, so this is untested.
if ( event - > key ( ) = = Qt : : Key_CapsLock ) {
2023-04-09 19:26:56 -03:00
keyboard_input ( 1 , 0x3a ) ;
keyboard_input ( 0 , 0x3a ) ;
2021-11-30 16:26:49 +06:00
}
2022-03-19 23:06:17 +00:00
} else {
2023-04-10 12:57:42 -03:00
/* Apple ISO keyboards are notorious for swapping ISO_Section and ANSI_Grave
on * some * layouts and / or models . While macOS can sort this mess out at
keymap level , it still provides applications with unfiltered , ambiguous
keycodes , so we have to disambiguate them by making some bold assumptions
about the user ' s keyboard layout based on the OS - provided key mappings . */
auto nvk = event - > nativeVirtualKey ( ) ;
if ( ( nvk = = 0x0a ) | | ( nvk = = 0x32 ) ) {
/* Flaws:
- Layouts with ` ~ on ISO_Section are partially detected due to a conflict with ANSI
- Czech and Slovak are not detected as they have < > ANSI_Grave and \ | ISO_Section ( differing from PC actually )
- Italian is partially detected due to \ | conflicting with Brazilian
- Romanian third level ANSI_Grave is unknown
- Russian clusters < > , plusminus and paragraph into a four - level ANSI_Grave , with the aforementioned ` ~ on ISO_Section */
auto key = event - > key ( ) ;
if ( ( nvk = = 0x32 ) & & ( /* system reports ANSI_Grave for ISO_Section keys: */
( key = = Qt : : Key_Less ) | | ( key = = Qt : : Key_Greater ) | | /* Croatian, French, German, Icelandic, Italian, Norwegian, Portuguese, Spanish, Spanish Latin America, Turkish Q */
( key = = Qt : : Key_Ugrave ) | | /* French Canadian */
( key = = Qt : : Key_Icircumflex ) | | /* Romanian */
( key = = Qt : : Key_Iacute ) | | /* Hungarian */
( key = = Qt : : Key_BracketLeft ) | | ( key = = Qt : : Key_BracketRight ) | | /* Russian upper two levels */
( key = = Qt : : Key_W ) /* Turkish F */
) )
mac_iso_swap = true ;
else if ( ( nvk = = 0x0a ) & & ( /* system reports ISO_Section for ANSI_Grave keys: */
( key = = Qt : : Key_paragraph ) | | ( key = = Qt : : Key_plusminus ) | | /* Arabic, British, Bulgarian, Danish shifted, Dutch, Greek, Hebrew, Hungarian shifted, International English, Norwegian shifted, Portuguese, Russian lower two levels, Swiss unshifted, Swedish unshifted, Turkish F */
( key = = Qt : : Key_At ) | | ( key = = Qt : : Key_NumberSign ) | | /* Belgian, French */
( key = = Qt : : Key_Apostrophe ) | | /* Brazilian unshifted */
( key = = Qt : : Key_QuoteDbl ) | | /* Brazilian shifted, Turkish Q unshifted */
( key = = Qt : : Key_QuoteLeft ) | | /* Croatian (right quote unknown) */
( key = = Qt : : Key_Dollar ) | | /* Danish unshifted */
2023-04-10 15:21:14 -03:00
( key = = Qt : : Key_AsciiCircum ) | | ( key = = 0x1ffffff ) | | /* German unshifted (0x1ffffff according to one tester), Polish unshifted */
2023-04-10 12:57:42 -03:00
( key = = Qt : : Key_degree ) | | /* German shifted, Icelandic unshifted, Spanish Latin America shifted, Swiss shifted, Swedish shifted */
( key = = Qt : : Key_0 ) | | /* Hungarian unshifted */
( key = = Qt : : Key_diaeresis ) | | /* Icelandic shifted */
( key = = Qt : : Key_acute ) | | /* Norwegian unshifted */
( key = = Qt : : Key_Asterisk ) | | /* Polish shifted */
( key = = Qt : : Key_masculine ) | | ( key = = Qt : : Key_ordfeminine ) | | /* Spanish (masculine unconfirmed) */
( key = = Qt : : Key_Eacute ) | | /* Turkish Q shifted */
( key = = Qt : : Key_Slash ) /* French Canadian unshifted, Ukrainian shifted */
) )
mac_iso_swap = true ;
2023-04-10 15:21:14 -03:00
#if 0
2023-04-10 12:57:42 -03:00
if ( down ) {
QMessageBox questionbox ( QMessageBox : : Icon : : Information , QString ( " Mac key swap test " ) , QString ( " nativeVirtualKey 0x%1 \n nativeScanCode 0x%2 \n key 0x%3 \n mac_iso_swap %4 " ) . arg ( nvk , 0 , 16 ) . arg ( event - > nativeScanCode ( ) , 0 , 16 ) . arg ( key , 0 , 16 ) . arg ( mac_iso_swap ? " yes " : " no " ) , QMessageBox : : Ok , this ) ;
questionbox . exec ( ) ;
}
2021-11-30 16:26:49 +06:00
# endif
2023-04-10 12:57:42 -03:00
if ( mac_iso_swap )
nvk = ( nvk = = 0x0a ) ? 0x32 : 0x0a ;
}
2023-07-11 16:49:14 -04:00
// Special case for command + forward delete to send insert.
if ( ( event - > nativeModifiers ( ) & NSEventModifierFlagCommand ) & &
( ( event - > nativeVirtualKey ( ) = = nvk_Delete ) | | event - > key ( ) = = Qt : : Key_Delete ) ) {
nvk = nvk_Insert ; // Qt::Key_Help according to event->key()
}
2023-04-10 12:57:42 -03:00
processKeyboardInput ( down , nvk ) ;
2021-12-24 16:31:36 +06:00
}
2021-11-30 16:26:49 +06:00
}
2022-03-19 23:06:17 +00:00
# endif
2021-11-25 10:20:56 +01:00
2022-11-19 08:49:04 -05:00
void
MainWindow : : on_actionFullscreen_triggered ( )
{
2021-11-30 21:26:51 +01:00
if ( video_fullscreen > 0 ) {
2021-12-23 17:05:11 +06:00
showNormal ( ) ;
2021-12-09 19:48:56 +01:00
ui - > menubar - > show ( ) ;
2022-11-19 08:49:04 -05:00
if ( ! hide_status_bar )
ui - > statusbar - > show ( ) ;
if ( ! hide_tool_bar )
ui - > toolBar - > show ( ) ;
2021-11-30 21:26:51 +01:00
video_fullscreen = 0 ;
2021-12-25 15:28:48 +06:00
if ( vid_resize ! = 1 ) {
2022-07-13 20:39:29 +06:00
emit resizeContents ( vid_resize = = 2 ? fixed_size_x : monitors [ 0 ] . mon_scrnsz_x , vid_resize = = 2 ? fixed_size_y : monitors [ 0 ] . mon_scrnsz_y ) ;
2021-12-25 15:28:48 +06:00
}
2021-11-30 21:26:51 +01:00
} else {
2022-02-27 14:56:51 +02:00
video_fullscreen = 1 ;
2021-12-25 15:28:48 +06:00
setFixedSize ( QWIDGETSIZE_MAX , QWIDGETSIZE_MAX ) ;
2021-12-09 19:48:56 +01:00
ui - > menubar - > hide ( ) ;
ui - > statusbar - > hide ( ) ;
2022-01-09 17:00:16 +02:00
ui - > toolBar - > hide ( ) ;
2022-10-30 23:29:23 +06:00
ui - > stackedWidget - > setFixedSize ( QWIDGETSIZE_MAX , QWIDGETSIZE_MAX ) ;
2021-11-30 21:26:51 +01:00
showFullScreen ( ) ;
}
2024-08-07 23:21:58 +02:00
fs_on_signal = false ;
fs_off_signal = false ;
2022-02-27 14:56:51 +02:00
ui - > stackedWidget - > onResize ( width ( ) , height ( ) ) ;
2021-11-25 10:20:56 +01:00
}
2021-11-29 17:25:31 +01:00
2022-11-19 08:49:04 -05:00
void
MainWindow : : getTitle_ ( wchar_t * title )
2021-12-01 15:55:41 +06:00
{
this - > windowTitle ( ) . toWCharArray ( title ) ;
}
2022-11-19 08:49:04 -05:00
void
MainWindow : : getTitle ( wchar_t * title )
2021-12-01 15:55:41 +06:00
{
if ( QThread : : currentThread ( ) = = this - > thread ( ) ) {
getTitle_ ( title ) ;
} else {
emit getTitleForNonQtThread ( title ) ;
}
}
2025-04-20 13:59:52 -07:00
// Helper to find an accelerator key and return it's sequence
// TODO: Is there a more central place to put this?
QKeySequence
MainWindow : : FindAcceleratorSeq ( const char * name )
{
int accID = FindAccelerator ( name ) ;
if ( accID = = - 1 )
return false ;
return ( QKeySequence : : fromString ( acc_keys [ accID ] . seq ) ) ;
}
2022-11-19 08:49:04 -05:00
bool
MainWindow : : eventFilter ( QObject * receiver , QEvent * event )
2021-12-05 15:57:46 +06:00
{
2025-04-20 14:28:10 -07:00
// Detect shortcuts when menubar is hidden
// TODO: Could this be simplified by proxying the event and manually
// shoving it into the menubar?
if ( event - > type ( ) = = QEvent : : KeyPress )
{
this - > keyPressEvent ( ( QKeyEvent * ) event ) ;
2025-04-20 15:23:38 -07:00
// We check for mouse release even if we aren't fullscreen,
// because it's not a menu accelerator.
if ( event - > type ( ) = = QEvent : : KeyPress )
2025-04-20 14:28:10 -07:00
{
QKeyEvent * ke = ( QKeyEvent * ) event ;
2025-08-28 01:41:29 +06:00
if ( ( QKeySequence ) ( ke - > key ( ) | ( ke - > modifiers ( ) & ~ Qt : : KeypadModifier ) ) = = FindAcceleratorSeq ( " release_mouse " ) | |
( QKeySequence ) ( ke - > key ( ) | ke - > modifiers ( ) ) = = FindAcceleratorSeq ( " release_mouse " ) )
2025-04-20 14:28:10 -07:00
{
plat_mouse_capture ( 0 ) ;
}
2025-04-20 15:23:38 -07:00
}
if ( event - > type ( ) = = QEvent : : KeyPress & & video_fullscreen ! = 0 )
{
QKeyEvent * ke = ( QKeyEvent * ) event ;
2025-08-28 01:41:29 +06:00
if ( ( QKeySequence ) ( ke - > key ( ) | ( ke - > modifiers ( ) & ~ Qt : : KeypadModifier ) ) = = FindAcceleratorSeq ( " screenshot " )
| | ( QKeySequence ) ( ke - > key ( ) | ke - > modifiers ( ) ) = = FindAcceleratorSeq ( " screenshot " ) )
2025-04-20 14:28:10 -07:00
{
ui - > actionTake_screenshot - > trigger ( ) ;
}
2025-08-28 01:41:29 +06:00
if ( ( QKeySequence ) ( ke - > key ( ) | ( ke - > modifiers ( ) & ~ Qt : : KeypadModifier ) ) = = FindAcceleratorSeq ( " fullscreen " )
| | ( QKeySequence ) ( ke - > key ( ) | ke - > modifiers ( ) ) = = FindAcceleratorSeq ( " fullscreen " ) )
2025-04-20 14:28:10 -07:00
{
ui - > actionFullscreen - > trigger ( ) ;
}
2025-08-28 01:41:29 +06:00
if ( ( QKeySequence ) ( ke - > key ( ) | ( ke - > modifiers ( ) & ~ Qt : : KeypadModifier ) ) = = FindAcceleratorSeq ( " hard_reset " )
| | ( QKeySequence ) ( ke - > key ( ) | ke - > modifiers ( ) ) = = FindAcceleratorSeq ( " hard_reset " ) )
2025-04-20 14:28:10 -07:00
{
ui - > actionHard_Reset - > trigger ( ) ;
}
2025-08-28 01:41:29 +06:00
if ( ( QKeySequence ) ( ke - > key ( ) | ( ke - > modifiers ( ) & ~ Qt : : KeypadModifier ) ) = = FindAcceleratorSeq ( " send_ctrl_alt_del " )
| | ( QKeySequence ) ( ke - > key ( ) | ke - > modifiers ( ) ) = = FindAcceleratorSeq ( " send_ctrl_alt_del " ) )
2025-04-20 14:28:10 -07:00
{
ui - > actionCtrl_Alt_Del - > trigger ( ) ;
}
2025-08-28 01:41:29 +06:00
if ( ( QKeySequence ) ( ke - > key ( ) | ( ke - > modifiers ( ) & ~ Qt : : KeypadModifier ) ) = = FindAcceleratorSeq ( " send_ctrl_alt_esc " )
| | ( QKeySequence ) ( ke - > key ( ) | ke - > modifiers ( ) ) = = FindAcceleratorSeq ( " send_ctrl_alt_esc " ) )
2025-04-20 14:28:10 -07:00
{
ui - > actionCtrl_Alt_Esc - > trigger ( ) ;
}
2025-08-28 01:41:29 +06:00
if ( ( QKeySequence ) ( ke - > key ( ) | ( ke - > modifiers ( ) & ~ Qt : : KeypadModifier ) ) = = FindAcceleratorSeq ( " pause " )
| | ( QKeySequence ) ( ke - > key ( ) | ke - > modifiers ( ) ) = = FindAcceleratorSeq ( " pause " ) )
2025-04-20 14:28:10 -07:00
{
ui - > actionPause - > trigger ( ) ;
}
2025-08-28 01:41:29 +06:00
if ( ( QKeySequence ) ( ke - > key ( ) | ( ke - > modifiers ( ) & ~ Qt : : KeypadModifier ) ) = = FindAcceleratorSeq ( " mute " )
| | ( QKeySequence ) ( ke - > key ( ) | ke - > modifiers ( ) ) = = FindAcceleratorSeq ( " mute " ) )
2025-04-20 14:31:46 -07:00
{
2025-04-20 14:33:19 -07:00
ui - > actionMute_Unmute - > trigger ( ) ;
2025-04-20 14:31:46 -07:00
}
2025-04-20 14:28:10 -07:00
return true ;
}
}
2025-08-01 02:31:29 +05:00
if ( ! dopause & & ( ! kbd_req_capture | | mouse_capture ) ) {
2022-03-21 15:28:43 +06:00
if ( event - > type ( ) = = QEvent : : Shortcut ) {
2022-11-19 08:49:04 -05:00
auto shortcutEvent = ( QShortcutEvent * ) event ;
2022-03-21 15:28:43 +06:00
if ( shortcutEvent - > key ( ) = = ui - > actionExit - > shortcut ( ) ) {
event - > accept ( ) ;
return true ;
}
}
2021-12-05 15:57:46 +06:00
if ( event - > type ( ) = = QEvent : : KeyPress ) {
2025-04-20 13:59:52 -07:00
event - > accept ( ) ;
2025-04-20 14:28:10 -07:00
2021-12-05 15:57:46 +06:00
return true ;
}
if ( event - > type ( ) = = QEvent : : KeyRelease ) {
event - > accept ( ) ;
2022-03-16 18:19:44 +02:00
this - > keyReleaseEvent ( ( QKeyEvent * ) event ) ;
2021-12-05 15:57:46 +06:00
return true ;
}
}
2021-12-06 21:26:17 +01:00
2022-03-16 18:19:44 +02:00
if ( receiver = = this ) {
2022-02-04 15:19:18 +06:00
static auto curdopause = dopause ;
2022-03-16 18:19:44 +02:00
if ( event - > type ( ) = = QEvent : : WindowBlocked ) {
2025-07-12 15:33:56 +06:00
window_blocked = true ;
2022-03-16 18:19:44 +02:00
curdopause = dopause ;
2025-08-21 02:32:36 +06:00
plat_pause ( isNonPause ? dopause : ( isShowMessage ? 2 : 1 ) ) ;
2022-03-16 18:19:44 +02:00
emit setMouseCapture ( false ) ;
2025-05-07 17:41:59 +06:00
releaseKeyboard ( ) ;
2022-03-16 18:19:44 +02:00
} else if ( event - > type ( ) = = QEvent : : WindowUnblocked ) {
2025-07-12 15:33:56 +06:00
window_blocked = false ;
2022-03-16 18:19:44 +02:00
plat_pause ( curdopause ) ;
}
2022-02-04 15:19:18 +06:00
}
2025-04-20 13:43:14 -07:00
2021-12-05 15:57:46 +06:00
return QMainWindow : : eventFilter ( receiver , event ) ;
}
2022-11-19 08:49:04 -05:00
void
MainWindow : : refreshMediaMenu ( )
{
2021-12-03 11:38:00 +01:00
mm - > refresh ( ui - > menuMedia ) ;
2025-04-11 05:26:01 +05:00
status - > setSoundMenu ( ui - > menuSound ) ;
2021-12-14 00:31:55 +06:00
status - > refresh ( ui - > statusbar ) ;
2022-06-04 14:15:31 +06:00
ui - > actionMCA_devices - > setVisible ( machine_has_bus ( machine , MACHINE_BUS_MCA ) ) ;
2023-02-06 01:39:34 +06:00
ui - > actionACPI_Shutdown - > setEnabled ( ! ! acpi_enabled ) ;
2025-03-27 16:31:32 +06:00
2025-05-08 00:28:25 +06:00
num_label - > setToolTip ( QShortcut : : tr ( " Num Lock " ) ) ;
2025-05-06 13:06:44 +06:00
num_label - > setVisible ( machine_has_bus ( machine , MACHINE_BUS_PS2_PORTS | MACHINE_BUS_AT_KBD ) ) ;
2025-05-08 00:28:25 +06:00
scroll_label - > setToolTip ( QShortcut : : tr ( " Scroll Lock " ) ) ;
2025-05-06 13:06:44 +06:00
scroll_label - > setVisible ( machine_has_bus ( machine , MACHINE_BUS_PS2_PORTS | MACHINE_BUS_AT_KBD ) ) ;
2025-05-08 00:28:25 +06:00
caps_label - > setToolTip ( QShortcut : : tr ( " Caps Lock " ) ) ;
2025-05-06 13:06:44 +06:00
caps_label - > setVisible ( machine_has_bus ( machine , MACHINE_BUS_PS2_PORTS | MACHINE_BUS_AT_KBD ) ) ;
2025-05-08 00:28:25 +06:00
kana_label - > setToolTip ( QShortcut : : tr ( " Kana Lock " ) ) ;
2025-07-27 15:23:43 +02:00
int ext_ax_kbd = machine_has_bus ( machine , MACHINE_BUS_PS2_PORTS | MACHINE_BUS_AT_KBD ) & &
( keyboard_type = = KEYBOARD_TYPE_AX ) ;
int int_ax_kbd = machine_has_flags ( machine , MACHINE_KEYBOARD_JIS ) & &
! machine_has_bus ( machine , MACHINE_BUS_PS2_PORTS ) ;
kana_label - > setVisible ( ext_ax_kbd | | int_ax_kbd ) ;
2025-08-21 02:32:36 +06:00
bool enable_comp_option = false ;
for ( int i = 0 ; i < MONITORS_NUM ; i + + ) {
if ( monitors [ i ] . mon_composite ) { enable_comp_option = true ; break ; }
}
ui - > actionCGA_composite_settings - > setEnabled ( enable_comp_option ) ;
2021-12-03 11:38:00 +01:00
}
2022-11-19 08:49:04 -05:00
void
2025-04-16 19:56:48 +05:00
MainWindow : : showMessage ( int flags , const QString & header , const QString & message , bool richText )
2022-11-19 08:49:04 -05:00
{
2021-11-29 17:25:31 +01:00
if ( QThread : : currentThread ( ) = = this - > thread ( ) ) {
2025-03-10 13:27:29 +06:00
if ( ! cpu_thread_running ) {
2025-04-16 19:56:48 +05:00
showMessageForNonQtThread ( flags , header , message , richText , nullptr ) ;
2025-03-10 13:27:29 +06:00
}
else
2025-04-16 19:56:48 +05:00
showMessage_ ( flags , header , message , richText ) ;
2021-11-29 17:25:31 +01:00
} else {
2024-06-26 23:09:55 +02:00
std : : atomic_bool done = false ;
2025-04-16 19:56:48 +05:00
emit showMessageForNonQtThread ( flags , header , message , richText , & done ) ;
2024-06-26 23:09:55 +02:00
while ( ! done ) {
QThread : : msleep ( 1 ) ;
}
2021-11-29 17:25:31 +01:00
}
}
2022-11-19 08:49:04 -05:00
void
2025-04-16 19:56:48 +05:00
MainWindow : : showMessage_ ( int flags , const QString & header , const QString & message , bool richText , std : : atomic_bool * done )
2022-11-19 08:49:04 -05:00
{
2024-06-26 23:09:55 +02:00
if ( done ) {
* done = false ;
}
2025-03-10 13:27:29 +06:00
isShowMessage = true ;
2021-11-29 17:25:31 +01:00
QMessageBox box ( QMessageBox : : Warning , header , message , QMessageBox : : NoButton , this ) ;
2022-07-09 13:51:12 +06:00
if ( flags & ( MBX_FATAL ) ) {
box . setIcon ( QMessageBox : : Critical ) ;
2022-11-19 08:49:04 -05:00
} else if ( ! ( flags & ( MBX_ERROR | MBX_WARNING ) ) ) {
2022-07-09 13:51:12 +06:00
box . setIcon ( QMessageBox : : Warning ) ;
}
2025-04-16 19:56:48 +05:00
if ( richText )
box . setTextFormat ( Qt : : TextFormat : : RichText ) ;
2021-11-29 17:25:31 +01:00
box . exec ( ) ;
2024-06-26 23:09:55 +02:00
if ( done ) {
* done = true ;
}
2025-03-10 13:27:29 +06:00
isShowMessage = false ;
2022-11-19 08:49:04 -05:00
if ( cpu_thread_run = = 0 )
QApplication : : exit ( - 1 ) ;
2021-11-29 17:25:31 +01:00
}
2021-11-30 16:26:49 +06:00
2022-11-19 08:49:04 -05:00
void
MainWindow : : keyPressEvent ( QKeyEvent * event )
2021-11-30 16:26:49 +06:00
{
2024-08-07 06:11:50 +02:00
if ( send_keyboard_input ) {
2022-03-19 23:06:17 +00:00
# ifdef Q_OS_MACOS
2023-04-09 16:36:36 -03:00
processMacKeyboardInput ( true , event ) ;
2021-11-30 16:26:49 +06:00
# else
2023-04-09 19:26:56 -03:00
processKeyboardInput ( true , event - > nativeScanCode ( ) ) ;
2021-11-30 16:26:49 +06:00
# endif
2021-12-09 20:59:50 +02:00
}
2025-04-19 19:44:47 -07:00
2021-12-05 15:57:46 +06:00
event - > accept ( ) ;
2021-11-30 16:26:49 +06:00
}
2022-11-19 08:49:04 -05:00
void
MainWindow : : blitToWidget ( int x , int y , int w , int h , int monitor_index )
2021-12-02 00:47:02 +06:00
{
2022-07-04 01:50:42 +06:00
if ( monitor_index > = 1 ) {
2024-02-13 18:40:07 +05:00
if ( renderers [ monitor_index ] & & renderers [ monitor_index ] - > isVisible ( ) )
2022-11-19 08:49:04 -05:00
renderers [ monitor_index ] - > blit ( x , y , w , h ) ;
else
video_blit_complete_monitor ( monitor_index ) ;
} else
ui - > stackedWidget - > blit ( x , y , w , h ) ;
2021-12-02 00:47:02 +06:00
}
2022-11-19 08:49:04 -05:00
void
MainWindow : : keyReleaseEvent ( QKeyEvent * event )
2021-11-30 16:26:49 +06:00
{
2022-08-23 16:32:38 +06:00
if ( event - > key ( ) = = Qt : : Key_Pause ) {
2024-08-07 06:11:50 +02:00
if ( keyboard_recv_ui ( 0x38 ) & & keyboard_recv_ui ( 0x138 ) ) {
2022-09-03 02:28:00 +06:00
plat_pause ( dopause ^ 1 ) ;
}
2022-08-23 16:32:38 +06:00
}
2021-12-09 20:59:50 +02:00
2023-07-24 17:16:01 -03:00
if ( send_keyboard_input & & ! event - > isAutoRepeat ( ) ) {
2022-03-19 23:06:17 +00:00
# ifdef Q_OS_MACOS
2023-07-24 17:16:01 -03:00
processMacKeyboardInput ( false , event ) ;
2021-11-30 16:26:49 +06:00
# else
2023-07-24 17:16:01 -03:00
processKeyboardInput ( false , event - > nativeScanCode ( ) ) ;
2021-11-30 16:26:49 +06:00
# endif
2023-07-24 17:16:01 -03:00
}
2021-12-04 21:33:04 +01:00
}
2022-11-19 08:49:04 -05:00
QSize
MainWindow : : getRenderWidgetSize ( )
2021-12-12 01:16:27 +06:00
{
return ui - > stackedWidget - > size ( ) ;
2021-12-04 21:33:04 +01:00
}
2021-12-05 15:57:46 +06:00
2022-11-19 08:49:04 -05:00
void
MainWindow : : focusInEvent ( QFocusEvent * event )
2021-12-05 15:57:46 +06:00
{
2025-05-07 17:41:59 +06:00
//this->grabKeyboard();
2021-12-05 15:57:46 +06:00
}
2022-11-19 08:49:04 -05:00
void
MainWindow : : focusOutEvent ( QFocusEvent * event )
2021-12-05 15:57:46 +06:00
{
2025-05-07 17:41:59 +06:00
//this->releaseKeyboard();
2021-12-05 20:51:59 +01:00
}
2021-12-06 21:26:17 +01:00
2022-11-19 08:49:04 -05:00
void
MainWindow : : on_actionResizable_window_triggered ( bool checked )
{
2025-08-25 16:50:44 +06:00
hide ( ) ;
2021-12-06 21:26:17 +01:00
if ( checked ) {
vid_resize = 1 ;
setFixedSize ( QWIDGETSIZE_MAX , QWIDGETSIZE_MAX ) ;
2025-08-25 16:50:44 +06:00
setWindowFlag ( Qt : : MSWindowsFixedSizeDialogHint , false ) ;
setWindowFlag ( Qt : : WindowMaximizeButtonHint , true ) ;
2022-07-05 00:21:30 +06:00
for ( int i = 1 ; i < MONITORS_NUM ; i + + ) {
if ( monitors [ i ] . target_buffer ) {
2024-01-15 03:16:22 +01:00
renderers [ i ] - > setWindowFlag ( Qt : : WindowMaximizeButtonHint , true ) ;
2022-07-05 00:21:30 +06:00
renderers [ i ] - > setFixedSize ( QWIDGETSIZE_MAX , QWIDGETSIZE_MAX ) ;
}
}
2021-12-06 21:26:17 +01:00
} else {
vid_resize = 0 ;
2021-12-24 01:57:26 +06:00
setWindowFlag ( Qt : : WindowMaximizeButtonHint , false ) ;
setWindowFlag ( Qt : : MSWindowsFixedSizeDialogHint ) ;
2022-07-05 00:21:30 +06:00
for ( int i = 1 ; i < MONITORS_NUM ; i + + ) {
if ( monitors [ i ] . target_buffer ) {
2022-07-05 16:40:04 +06:00
renderers [ i ] - > setWindowFlag ( Qt : : WindowMaximizeButtonHint , false ) ;
2022-07-05 00:21:30 +06:00
emit resizeContentsMonitor ( monitors [ i ] . mon_scrnsz_x , monitors [ i ] . mon_scrnsz_y , i ) ;
}
}
2021-12-06 21:26:17 +01:00
}
2021-12-24 01:57:26 +06:00
show ( ) ;
2022-11-19 08:49:04 -05:00
ui - > menuWindow_scale_factor - > setEnabled ( ! checked ) ;
2022-07-04 01:50:42 +06:00
emit resizeContents ( monitors [ 0 ] . mon_scrnsz_x , monitors [ 0 ] . mon_scrnsz_y ) ;
2022-11-19 08:49:04 -05:00
ui - > stackedWidget - > switchRenderer ( ( RendererStack : : Renderer ) vid_api ) ;
2022-07-05 00:21:30 +06:00
for ( int i = 1 ; i < MONITORS_NUM ; i + + ) {
2022-07-10 17:06:16 +06:00
if ( monitors [ i ] . target_buffer & & show_second_monitors ) {
renderers [ i ] - > show ( ) ;
2022-11-19 08:49:04 -05:00
renderers [ i ] - > switchRenderer ( ( RendererStack : : Renderer ) vid_api ) ;
2022-07-05 00:21:30 +06:00
QApplication : : processEvents ( ) ;
}
}
2021-12-06 21:26:17 +01:00
}
2021-12-06 21:45:40 +01:00
static void
2022-11-19 08:49:04 -05:00
video_toggle_option ( QAction * action , int * val )
2021-12-06 21:45:40 +01:00
{
startblit ( ) ;
* val ^ = 1 ;
2021-12-08 15:12:21 +01:00
video_copy = ( video_grayscale | | invert_display ) ? video_transform_copy : memcpy ;
2021-12-06 21:45:40 +01:00
action - > setChecked ( * val > 0 ? true : false ) ;
endblit ( ) ;
config_save ( ) ;
2022-12-19 13:30:51 +06:00
reset_screen_size ( ) ;
2021-12-06 21:45:40 +01:00
device_force_redraw ( ) ;
2022-07-05 00:21:30 +06:00
for ( int i = 0 ; i < MONITORS_NUM ; i + + ) {
2022-11-19 08:49:04 -05:00
if ( monitors [ i ] . target_buffer )
video_force_resize_set_monitor ( 1 , i ) ;
2022-07-05 00:21:30 +06:00
}
2021-12-06 21:45:40 +01:00
}
2022-11-19 08:49:04 -05:00
void
MainWindow : : on_actionInverted_VGA_monitor_triggered ( )
{
2021-12-06 21:45:40 +01:00
video_toggle_option ( ui - > actionInverted_VGA_monitor , & invert_display ) ;
}
2021-12-06 21:58:41 +01:00
2022-11-19 08:49:04 -05:00
static void
update_scaled_checkboxes ( Ui : : MainWindow * ui , QAction * selected )
{
2021-12-06 21:58:41 +01:00
ui - > action0_5x - > setChecked ( ui - > action0_5x = = selected ) ;
ui - > action1x - > setChecked ( ui - > action1x = = selected ) ;
ui - > action1_5x - > setChecked ( ui - > action1_5x = = selected ) ;
ui - > action2x - > setChecked ( ui - > action2x = = selected ) ;
2022-11-01 11:53:49 -07:00
ui - > action3x - > setChecked ( ui - > action3x = = selected ) ;
ui - > action4x - > setChecked ( ui - > action4x = = selected ) ;
ui - > action5x - > setChecked ( ui - > action5x = = selected ) ;
ui - > action6x - > setChecked ( ui - > action6x = = selected ) ;
ui - > action7x - > setChecked ( ui - > action7x = = selected ) ;
ui - > action8x - > setChecked ( ui - > action8x = = selected ) ;
2021-12-06 21:58:41 +01:00
reset_screen_size ( ) ;
device_force_redraw ( ) ;
2022-07-05 00:21:30 +06:00
for ( int i = 0 ; i < MONITORS_NUM ; i + + ) {
2022-11-19 08:49:04 -05:00
if ( monitors [ i ] . target_buffer )
video_force_resize_set_monitor ( 1 , i ) ;
2022-07-05 00:21:30 +06:00
}
2021-12-06 21:58:41 +01:00
config_save ( ) ;
}
2022-11-19 08:49:04 -05:00
void
MainWindow : : on_action0_5x_triggered ( )
{
2021-12-06 21:58:41 +01:00
scale = 0 ;
update_scaled_checkboxes ( ui , ui - > action0_5x ) ;
}
2022-11-19 08:49:04 -05:00
void
MainWindow : : on_action1x_triggered ( )
{
2021-12-06 21:58:41 +01:00
scale = 1 ;
update_scaled_checkboxes ( ui , ui - > action1x ) ;
}
2022-11-19 08:49:04 -05:00
void
MainWindow : : on_action1_5x_triggered ( )
{
2021-12-06 21:58:41 +01:00
scale = 2 ;
update_scaled_checkboxes ( ui , ui - > action1_5x ) ;
}
2022-11-19 08:49:04 -05:00
void
MainWindow : : on_action2x_triggered ( )
{
2021-12-06 21:58:41 +01:00
scale = 3 ;
update_scaled_checkboxes ( ui , ui - > action2x ) ;
}
2022-11-19 08:49:04 -05:00
void
MainWindow : : on_action3x_triggered ( )
{
2022-11-01 11:53:49 -07:00
scale = 4 ;
update_scaled_checkboxes ( ui , ui - > action3x ) ;
}
2022-11-19 08:49:04 -05:00
void
MainWindow : : on_action4x_triggered ( )
{
2022-11-01 11:53:49 -07:00
scale = 5 ;
update_scaled_checkboxes ( ui , ui - > action4x ) ;
}
2022-11-19 08:49:04 -05:00
void
MainWindow : : on_action5x_triggered ( )
{
2022-11-01 11:53:49 -07:00
scale = 6 ;
update_scaled_checkboxes ( ui , ui - > action5x ) ;
}
2022-11-19 08:49:04 -05:00
void
MainWindow : : on_action6x_triggered ( )
{
2022-11-01 11:53:49 -07:00
scale = 7 ;
update_scaled_checkboxes ( ui , ui - > action6x ) ;
}
2022-11-19 08:49:04 -05:00
void
MainWindow : : on_action7x_triggered ( )
{
2022-11-01 11:53:49 -07:00
scale = 8 ;
update_scaled_checkboxes ( ui , ui - > action7x ) ;
}
2022-11-19 08:49:04 -05:00
void
MainWindow : : on_action8x_triggered ( )
{
2022-11-01 11:53:49 -07:00
scale = 9 ;
update_scaled_checkboxes ( ui , ui - > action8x ) ;
}
2022-11-19 08:49:04 -05:00
void
MainWindow : : on_actionNearest_triggered ( )
{
2021-12-06 22:02:18 +01:00
video_filter_method = 0 ;
ui - > actionLinear - > setChecked ( false ) ;
}
2022-11-19 08:49:04 -05:00
void
MainWindow : : on_actionLinear_triggered ( )
{
2021-12-06 22:02:18 +01:00
video_filter_method = 1 ;
ui - > actionNearest - > setChecked ( false ) ;
}
2021-12-07 13:47:42 +01:00
2022-11-19 08:49:04 -05:00
static void
update_fullscreen_scale_checkboxes ( Ui : : MainWindow * ui , QAction * selected )
{
2023-10-14 23:42:02 +02:00
ui - > actionFullScreen_stretch - > setChecked ( selected = = ui - > actionFullScreen_stretch ) ;
ui - > actionFullScreen_43 - > setChecked ( selected = = ui - > actionFullScreen_43 ) ;
ui - > actionFullScreen_keepRatio - > setChecked ( selected = = ui - > actionFullScreen_keepRatio ) ;
ui - > actionFullScreen_int - > setChecked ( selected = = ui - > actionFullScreen_int ) ;
ui - > actionFullScreen_int43 - > setChecked ( selected = = ui - > actionFullScreen_int43 ) ;
2021-12-07 13:47:42 +01:00
2022-08-10 01:27:54 +06:00
{
2021-12-07 13:47:42 +01:00
auto widget = ui - > stackedWidget - > currentWidget ( ) ;
2022-02-27 14:56:51 +02:00
ui - > stackedWidget - > onResize ( widget - > width ( ) , widget - > height ( ) ) ;
2021-12-07 13:47:42 +01:00
}
2022-08-10 01:27:54 +06:00
for ( int i = 1 ; i < MONITORS_NUM ; i + + ) {
2022-11-19 08:49:04 -05:00
if ( main_window - > renderers [ i ] )
2023-10-14 23:42:02 +02:00
main_window - > renderers [ i ] - > onResize ( main_window - > renderers [ i ] - > width ( ) ,
main_window - > renderers [ i ] - > height ( ) ) ;
2021-12-07 13:47:42 +01:00
}
device_force_redraw ( ) ;
config_save ( ) ;
}
2022-11-19 08:49:04 -05:00
void
MainWindow : : on_actionFullScreen_stretch_triggered ( )
{
2021-12-07 13:47:42 +01:00
video_fullscreen_scale = FULLSCR_SCALE_FULL ;
update_fullscreen_scale_checkboxes ( ui , ui - > actionFullScreen_stretch ) ;
}
2022-11-19 08:49:04 -05:00
void
MainWindow : : on_actionFullScreen_43_triggered ( )
{
2021-12-07 13:47:42 +01:00
video_fullscreen_scale = FULLSCR_SCALE_43 ;
update_fullscreen_scale_checkboxes ( ui , ui - > actionFullScreen_43 ) ;
}
2022-11-19 08:49:04 -05:00
void
MainWindow : : on_actionFullScreen_keepRatio_triggered ( )
{
2021-12-07 13:47:42 +01:00
video_fullscreen_scale = FULLSCR_SCALE_KEEPRATIO ;
update_fullscreen_scale_checkboxes ( ui , ui - > actionFullScreen_keepRatio ) ;
}
2022-11-19 08:49:04 -05:00
void
MainWindow : : on_actionFullScreen_int_triggered ( )
{
2021-12-07 13:47:42 +01:00
video_fullscreen_scale = FULLSCR_SCALE_INT ;
update_fullscreen_scale_checkboxes ( ui , ui - > actionFullScreen_int ) ;
}
2023-10-13 23:30:31 +02:00
void
MainWindow : : on_actionFullScreen_int43_triggered ( )
{
video_fullscreen_scale = FULLSCR_SCALE_INT43 ;
update_fullscreen_scale_checkboxes ( ui , ui - > actionFullScreen_int43 ) ;
}
2022-11-19 08:49:04 -05:00
static void
update_greyscale_checkboxes ( Ui : : MainWindow * ui , QAction * selected , int value )
{
2021-12-08 15:12:21 +01:00
ui - > actionRGB_Color - > setChecked ( ui - > actionRGB_Color = = selected ) ;
ui - > actionRGB_Grayscale - > setChecked ( ui - > actionRGB_Grayscale = = selected ) ;
ui - > actionAmber_monitor - > setChecked ( ui - > actionAmber_monitor = = selected ) ;
ui - > actionGreen_monitor - > setChecked ( ui - > actionGreen_monitor = = selected ) ;
ui - > actionWhite_monitor - > setChecked ( ui - > actionWhite_monitor = = selected ) ;
startblit ( ) ;
video_grayscale = value ;
2022-11-19 08:49:04 -05:00
video_copy = ( video_grayscale | | invert_display ) ? video_transform_copy : memcpy ;
2021-12-08 15:12:21 +01:00
endblit ( ) ;
device_force_redraw ( ) ;
config_save ( ) ;
}
2022-11-19 08:49:04 -05:00
void
MainWindow : : on_actionRGB_Color_triggered ( )
{
2021-12-08 15:12:21 +01:00
update_greyscale_checkboxes ( ui , ui - > actionRGB_Color , 0 ) ;
}
2022-11-19 08:49:04 -05:00
void
MainWindow : : on_actionRGB_Grayscale_triggered ( )
{
2021-12-08 15:12:21 +01:00
update_greyscale_checkboxes ( ui , ui - > actionRGB_Grayscale , 1 ) ;
}
2022-11-19 08:49:04 -05:00
void
MainWindow : : on_actionAmber_monitor_triggered ( )
{
2021-12-08 15:12:21 +01:00
update_greyscale_checkboxes ( ui , ui - > actionAmber_monitor , 2 ) ;
}
2022-11-19 08:49:04 -05:00
void
MainWindow : : on_actionGreen_monitor_triggered ( )
{
2021-12-08 15:12:21 +01:00
update_greyscale_checkboxes ( ui , ui - > actionGreen_monitor , 3 ) ;
}
2022-11-19 08:49:04 -05:00
void
MainWindow : : on_actionWhite_monitor_triggered ( )
{
2021-12-08 15:12:21 +01:00
update_greyscale_checkboxes ( ui , ui - > actionWhite_monitor , 4 ) ;
}
2021-12-08 15:17:33 +01:00
2022-11-19 08:49:04 -05:00
static void
update_greyscale_type_checkboxes ( Ui : : MainWindow * ui , QAction * selected , int value )
{
2021-12-08 15:17:33 +01:00
ui - > actionBT601_NTSC_PAL - > setChecked ( ui - > actionBT601_NTSC_PAL = = selected ) ;
ui - > actionBT709_HDTV - > setChecked ( ui - > actionBT709_HDTV = = selected ) ;
ui - > actionAverage - > setChecked ( ui - > actionAverage = = selected ) ;
video_graytype = value ;
device_force_redraw ( ) ;
config_save ( ) ;
}
2022-11-19 08:49:04 -05:00
void
MainWindow : : on_actionBT601_NTSC_PAL_triggered ( )
{
2021-12-08 15:17:33 +01:00
update_greyscale_type_checkboxes ( ui , ui - > actionBT601_NTSC_PAL , 0 ) ;
}
2022-11-19 08:49:04 -05:00
void
MainWindow : : on_actionBT709_HDTV_triggered ( )
{
2021-12-08 15:17:33 +01:00
update_greyscale_type_checkboxes ( ui , ui - > actionBT709_HDTV , 1 ) ;
}
2022-11-19 08:49:04 -05:00
void
MainWindow : : on_actionAverage_triggered ( )
{
2021-12-08 15:17:33 +01:00
update_greyscale_type_checkboxes ( ui , ui - > actionAverage , 2 ) ;
}
2021-12-09 20:59:50 +02:00
2022-11-19 08:49:04 -05:00
void
MainWindow : : on_actionAbout_Qt_triggered ( )
2021-12-09 16:27:53 +06:00
{
QApplication : : aboutQt ( ) ;
}
2022-11-19 08:49:04 -05:00
void
MainWindow : : on_actionAbout_86Box_triggered ( )
2021-12-09 16:27:53 +06:00
{
2025-07-27 04:31:13 +05:00
const auto msgBox = new About ( this ) ;
msgBox - > exec ( ) ;
2021-12-09 16:27:53 +06:00
}
2022-11-19 08:49:04 -05:00
void
MainWindow : : on_actionDocumentation_triggered ( )
2021-12-09 16:27:53 +06:00
{
2022-11-19 08:49:04 -05:00
QDesktopServices : : openUrl ( QUrl ( EMU_DOCS_URL ) ) ;
2021-12-09 16:27:53 +06:00
}
2021-12-09 19:36:35 +01:00
2022-11-19 08:49:04 -05:00
void
MainWindow : : on_actionCGA_PCjr_Tandy_EGA_S_VGA_overscan_triggered ( )
{
2021-12-09 11:55:28 +01:00
update_overscan = 1 ;
video_toggle_option ( ui - > actionCGA_PCjr_Tandy_EGA_S_VGA_overscan , & enable_overscan ) ;
}
2022-11-19 08:49:04 -05:00
void
MainWindow : : on_actionChange_contrast_for_monochrome_display_triggered ( )
{
2025-08-24 00:08:00 +06:00
startblit ( ) ;
2021-12-09 11:55:28 +01:00
vid_cga_contrast ^ = 1 ;
2025-08-24 00:08:00 +06:00
for ( int i = 0 ; i < MONITORS_NUM ; i + + )
cgapal_rebuild_monitor ( i ) ;
2021-12-09 11:55:28 +01:00
config_save ( ) ;
2025-08-24 00:08:00 +06:00
endblit ( ) ;
2021-12-09 11:55:28 +01:00
}
2022-11-19 08:49:04 -05:00
void
MainWindow : : on_actionForce_4_3_display_ratio_triggered ( )
{
2021-12-09 11:55:28 +01:00
video_toggle_option ( ui - > actionForce_4_3_display_ratio , & force_43 ) ;
}
2021-12-09 21:02:10 +02:00
2023-10-13 23:30:31 +02:00
void
MainWindow : : on_actionAuto_pause_triggered ( )
{
do_auto_pause ^ = 1 ;
ui - > actionAuto_pause - > setChecked ( do_auto_pause > 0 ? true : false ) ;
2025-08-19 21:03:09 +02:00
config_save ( ) ;
}
void
MainWindow : : on_actionUpdate_mouse_every_CPU_frame_triggered ( )
{
force_constant_mouse ^ = 1 ;
ui - > actionUpdate_mouse_every_CPU_frame - > setChecked ( force_constant_mouse > 0 ? true : false ) ;
mouse_update_sample_rate ( ) ;
config_save ( ) ;
2023-10-13 23:30:31 +02:00
}
2022-11-19 08:49:04 -05:00
void
MainWindow : : on_actionRemember_size_and_position_triggered ( )
2021-12-12 01:16:27 +06:00
{
window_remember ^ = 1 ;
2023-07-27 01:26:24 +02:00
if ( ! video_fullscreen ) {
window_w = ui - > stackedWidget - > width ( ) ;
window_h = ui - > stackedWidget - > height ( ) ;
if ( ! QApplication : : platformName ( ) . contains ( " wayland " ) ) {
window_x = geometry ( ) . x ( ) ;
window_y = geometry ( ) . y ( ) ;
}
for ( int i = 1 ; i < MONITORS_NUM ; i + + ) {
if ( window_remember & & renderers [ i ] ) {
monitor_settings [ i ] . mon_window_w = renderers [ i ] - > geometry ( ) . width ( ) ;
monitor_settings [ i ] . mon_window_h = renderers [ i ] - > geometry ( ) . height ( ) ;
monitor_settings [ i ] . mon_window_x = renderers [ i ] - > geometry ( ) . x ( ) ;
monitor_settings [ i ] . mon_window_y = renderers [ i ] - > geometry ( ) . y ( ) ;
}
2022-07-05 16:40:04 +06:00
}
2021-12-12 01:16:27 +06:00
}
ui - > actionRemember_size_and_position - > setChecked ( window_remember ) ;
}
2022-11-19 08:49:04 -05:00
void
MainWindow : : on_actionSpecify_dimensions_triggered ( )
2021-12-12 01:16:27 +06:00
{
SpecifyDimensions dialog ( this ) ;
dialog . setWindowModality ( Qt : : WindowModal ) ;
dialog . exec ( ) ;
}
2022-11-19 08:49:04 -05:00
void
MainWindow : : on_actionHiDPI_scaling_triggered ( )
2021-12-12 01:16:27 +06:00
{
dpi_scale ^ = 1 ;
ui - > actionHiDPI_scaling - > setChecked ( dpi_scale ) ;
2022-07-04 01:50:42 +06:00
emit resizeContents ( monitors [ 0 ] . mon_scrnsz_x , monitors [ 0 ] . mon_scrnsz_y ) ;
2022-07-06 01:25:39 +06:00
for ( int i = 1 ; i < MONITORS_NUM ; i + + ) {
2022-11-19 08:49:04 -05:00
if ( renderers [ i ] )
emit resizeContentsMonitor ( monitors [ i ] . mon_scrnsz_x , monitors [ i ] . mon_scrnsz_y , i ) ;
2022-07-06 01:25:39 +06:00
}
2021-12-12 01:16:27 +06:00
}
2022-11-19 08:49:04 -05:00
void
MainWindow : : on_actionHide_status_bar_triggered ( )
2021-12-12 01:16:27 +06:00
{
hide_status_bar ^ = 1 ;
ui - > actionHide_status_bar - > setChecked ( hide_status_bar ) ;
statusBar ( ) - > setVisible ( ! hide_status_bar ) ;
2025-03-01 15:54:50 +05:00
# ifdef Q_OS_WINDOWS
2025-03-07 00:11:45 +05:00
util : : setWin11RoundedCorners ( main_window - > winId ( ) , ( hide_status_bar ? false : true ) ) ;
2025-03-01 15:54:50 +05:00
# endif
2022-01-09 17:00:16 +02:00
if ( vid_resize > = 2 ) {
2022-11-19 08:49:04 -05:00
setFixedSize ( fixed_size_x , fixed_size_y + menuBar ( ) - > height ( ) + ( hide_status_bar ? 0 : statusBar ( ) - > height ( ) ) + ( hide_tool_bar ? 0 : ui - > toolBar - > height ( ) ) ) ;
2022-01-09 17:00:16 +02:00
} else {
int vid_resize_orig = vid_resize ;
2022-11-19 08:49:04 -05:00
vid_resize = 0 ;
2025-08-26 00:44:15 +02:00
emit resizeContents ( monitors [ 0 ] . mon_scrnsz_x , monitors [ 0 ] . mon_scrnsz_y ) ;
2022-01-09 17:00:16 +02:00
vid_resize = vid_resize_orig ;
2022-11-19 08:49:04 -05:00
if ( vid_resize = = 1 )
setFixedSize ( QWIDGETSIZE_MAX , QWIDGETSIZE_MAX ) ;
2022-01-09 17:00:16 +02:00
}
}
2022-11-19 08:49:04 -05:00
void
MainWindow : : on_actionHide_tool_bar_triggered ( )
2022-01-09 17:00:16 +02:00
{
hide_tool_bar ^ = 1 ;
ui - > actionHide_tool_bar - > setChecked ( hide_tool_bar ) ;
ui - > toolBar - > setVisible ( ! hide_tool_bar ) ;
if ( vid_resize > = 2 ) {
2022-11-19 08:49:04 -05:00
setFixedSize ( fixed_size_x , fixed_size_y + menuBar ( ) - > height ( ) + ( hide_status_bar ? 0 : statusBar ( ) - > height ( ) ) + ( hide_tool_bar ? 0 : ui - > toolBar - > height ( ) ) ) ;
2022-01-09 17:00:16 +02:00
} else {
2021-12-12 01:16:27 +06:00
int vid_resize_orig = vid_resize ;
2022-11-19 08:49:04 -05:00
vid_resize = 0 ;
2025-08-26 00:44:15 +02:00
emit resizeContents ( monitors [ 0 ] . mon_scrnsz_x , monitors [ 0 ] . mon_scrnsz_y ) ;
2021-12-12 01:16:27 +06:00
vid_resize = vid_resize_orig ;
2022-11-19 08:49:04 -05:00
if ( vid_resize = = 1 )
setFixedSize ( QWIDGETSIZE_MAX , QWIDGETSIZE_MAX ) ;
2021-12-12 01:16:27 +06:00
}
}
2022-11-19 08:49:04 -05:00
void
MainWindow : : on_actionUpdate_status_bar_icons_triggered ( )
2021-12-12 01:16:27 +06:00
{
update_icons ^ = 1 ;
ui - > actionUpdate_status_bar_icons - > setChecked ( update_icons ) ;
2022-12-09 22:13:15 +02:00
/* Prevent icons staying when disabled during activity. */
status - > clearActivity ( ) ;
2021-12-12 01:16:27 +06:00
}
2022-11-19 08:49:04 -05:00
void
MainWindow : : on_actionTake_screenshot_triggered ( )
2021-12-12 01:16:27 +06:00
{
startblit ( ) ;
2024-05-03 17:02:13 +02:00
for ( auto & monitor : monitors )
+ + monitor . mon_screenshots ;
2021-12-12 01:16:27 +06:00
endblit ( ) ;
device_force_redraw ( ) ;
}
2021-12-12 16:22:35 +06:00
2025-04-11 05:26:01 +05:00
void
MainWindow : : on_actionMute_Unmute_triggered ( )
{
sound_muted ^ = 1 ;
config_save ( ) ;
status - > updateSoundIcon ( ) ;
ui - > actionMute_Unmute - > setText ( sound_muted ? tr ( " &Unmute " ) : tr ( " &Mute " ) ) ;
}
2022-11-19 08:49:04 -05:00
void
MainWindow : : on_actionSound_gain_triggered ( )
2021-12-12 16:22:35 +06:00
{
SoundGain gain ( this ) ;
gain . exec ( ) ;
}
2021-12-12 14:12:11 +02:00
2022-11-19 08:49:04 -05:00
void
MainWindow : : setSendKeyboardInput ( bool enabled )
2021-12-09 20:59:50 +02:00
{
send_keyboard_input = enabled ;
2021-12-18 01:03:05 +06:00
}
2021-12-27 16:32:03 +06:00
2022-11-19 08:49:04 -05:00
void
MainWindow : : updateUiPauseState ( )
2021-12-27 16:32:03 +06:00
{
2024-05-03 17:02:13 +02:00
const auto pause_icon = dopause ? QIcon ( " :/menuicons/qt/icons/run.ico " ) :
QIcon ( " :/menuicons/qt/icons/pause.ico " ) ;
const auto tooltip_text = dopause ? QString ( tr ( " Resume execution " ) ) :
QString ( tr ( " Pause execution " ) ) ;
2025-07-28 12:18:17 +05:00
const auto menu_text = dopause ? QString ( tr ( " Re&sume " ) ) :
QString ( tr ( " &Pause " ) ) ;
2022-10-28 13:48:59 -04:00
ui - > actionPause - > setIcon ( pause_icon ) ;
ui - > actionPause - > setToolTip ( tooltip_text ) ;
2025-07-28 12:18:17 +05:00
ui - > actionPause - > setText ( menu_text ) ;
2025-07-12 15:33:56 +06:00
emit vmmRunningStateChanged ( static_cast < VMManagerProtocol : : RunningState > ( window_blocked ? ( dopause ? VMManagerProtocol : : RunningState : : PausedWaiting : VMManagerProtocol : : RunningState : : RunningWaiting ) : ( VMManagerProtocol : : RunningState ) dopause ) ) ;
2021-12-27 16:32:03 +06:00
}
2021-12-28 16:47:10 +06:00
2024-09-18 09:38:47 +02:00
void
MainWindow : : updateStatusEmptyIcons ( )
{
if ( status ! = nullptr )
status - > refreshEmptyIcons ( ) ;
}
2022-11-19 08:49:04 -05:00
void
MainWindow : : on_actionPreferences_triggered ( )
2021-12-28 16:47:10 +06:00
{
ProgSettings progsettings ( this ) ;
2025-08-28 17:56:33 +06:00
if ( progsettings . exec ( ) = = QDialog : : Accepted ) {
emit vmmGlobalConfigurationChanged ( ) ;
}
2021-12-28 16:47:10 +06:00
}
2022-11-19 08:49:04 -05:00
void
MainWindow : : on_actionEnable_Discord_integration_triggered ( bool checked )
2022-01-09 01:04:59 +06:00
{
enable_discord = checked ;
2023-02-01 17:17:56 +01:00
# ifdef DISCORD
2022-11-19 08:49:04 -05:00
if ( enable_discord ) {
2022-01-09 01:04:59 +06:00
discord_init ( ) ;
discord_update_activity ( dopause ) ;
} else
discord_close ( ) ;
2023-02-01 17:17:56 +01:00
# endif
2022-01-09 01:04:59 +06:00
}
2022-11-19 08:49:04 -05:00
void
MainWindow : : showSettings ( )
2022-01-22 01:10:11 +02:00
{
2022-11-19 08:49:04 -05:00
if ( findChild < Settings * > ( ) = = nullptr )
2022-01-22 01:10:11 +02:00
ui - > actionSettings - > trigger ( ) ;
}
2022-11-19 08:49:04 -05:00
void
MainWindow : : hardReset ( )
2022-01-22 01:10:11 +02:00
{
ui - > actionHard_Reset - > trigger ( ) ;
2022-01-22 02:41:02 +02:00
}
2022-11-19 08:49:04 -05:00
void
MainWindow : : togglePause ( )
2022-01-22 02:41:02 +02:00
{
ui - > actionPause - > trigger ( ) ;
2022-01-22 22:00:44 +02:00
}
2022-11-19 08:49:04 -05:00
void
MainWindow : : changeEvent ( QEvent * event )
2022-01-22 22:00:44 +02:00
{
2022-01-27 21:26:30 +02:00
# ifdef Q_OS_WINDOWS
2022-11-19 08:49:04 -05:00
if ( event - > type ( ) = = QEvent : : LanguageChange ) {
2024-03-20 16:48:09 +05:00
QApplication : : setFont ( QFont ( ProgSettings : : getFontName ( lang_id ) , 9 ) ) ;
2022-01-22 22:00:44 +02:00
}
2022-01-27 21:26:30 +02:00
# endif
2022-01-22 22:00:44 +02:00
QWidget : : changeEvent ( event ) ;
2022-08-14 12:28:36 +06:00
if ( isVisible ( ) ) {
monitor_settings [ 0 ] . mon_window_maximized = isMaximized ( ) ;
config_save ( ) ;
}
2022-02-03 16:55:32 +06:00
}
2022-02-27 14:56:51 +02:00
2025-03-09 23:58:54 +06:00
void
MainWindow : : reloadAllRenderers ( )
{
reload_renderers = true ;
}
2022-11-19 08:49:04 -05:00
void
MainWindow : : on_actionRenderer_options_triggered ( )
2022-02-27 14:56:51 +02:00
{
2024-05-03 17:02:13 +02:00
if ( const auto dlg = ui - > stackedWidget - > getOptions ( this ) ) {
2022-07-07 14:34:59 +06:00
if ( dlg - > exec ( ) = = QDialog : : Accepted ) {
2025-03-09 01:39:07 +06:00
if ( ui - > stackedWidget - > reloadRendererOption ( ) ) {
ui - > stackedWidget - > switchRenderer ( static_cast < RendererStack : : Renderer > ( vid_api ) ) ;
if ( show_second_monitors ) {
for ( int i = 1 ; i < MONITORS_NUM ; i + + ) {
if ( renderers [ i ] & & renderers [ i ] - > reloadRendererOption ( ) & & renderers [ i ] - > hasOptions ( ) ) {
ui - > stackedWidget - > switchRenderer ( static_cast < RendererStack : : Renderer > ( vid_api ) ) ;
}
}
}
} else for ( int i = 1 ; i < MONITORS_NUM ; i + + ) {
2022-11-19 08:49:04 -05:00
if ( renderers [ i ] & & renderers [ i ] - > hasOptions ( ) )
renderers [ i ] - > reloadOptions ( ) ;
2022-07-07 14:34:59 +06:00
}
2025-03-09 23:58:54 +06:00
} else if ( reload_renderers & & ui - > stackedWidget - > reloadRendererOption ( ) ) {
reload_renderers = false ;
ui - > stackedWidget - > switchRenderer ( static_cast < RendererStack : : Renderer > ( vid_api ) ) ;
if ( show_second_monitors ) {
for ( int i = 1 ; i < MONITORS_NUM ; i + + ) {
2025-03-16 15:24:24 +06:00
if ( renderers [ i ] ) {
renderers [ i ] - > switchRenderer ( static_cast < RendererStack : : Renderer > ( vid_api ) ) ;
2025-03-09 23:58:54 +06:00
}
}
}
2022-07-07 14:34:59 +06:00
}
}
2022-02-27 14:56:51 +02:00
}
2022-05-23 17:29:45 +06:00
2022-11-19 08:49:04 -05:00
void
MainWindow : : on_actionMCA_devices_triggered ( )
2022-05-23 17:29:45 +06:00
{
2024-05-03 17:02:13 +02:00
if ( const auto dlg = new MCADeviceList ( this ) )
2022-05-23 17:29:45 +06:00
dlg - > exec ( ) ;
}
2022-11-19 08:49:04 -05:00
void
MainWindow : : on_actionShow_non_primary_monitors_triggered ( )
2022-07-10 11:41:02 +06:00
{
2024-05-03 17:02:13 +02:00
show_second_monitors = static_cast < int > ( ui - > actionShow_non_primary_monitors - > isChecked ( ) ) ;
2022-07-10 11:41:02 +06:00
if ( show_second_monitors ) {
for ( int monitor_index = 1 ; monitor_index < MONITORS_NUM ; monitor_index + + ) {
2024-05-03 17:02:13 +02:00
const auto & secondaryRenderer = renderers [ monitor_index ] ;
2022-11-19 08:49:04 -05:00
if ( ! renderers [ monitor_index ] )
continue ;
2022-07-10 11:41:02 +06:00
secondaryRenderer - > show ( ) ;
if ( window_remember ) {
secondaryRenderer - > setGeometry ( monitor_settings [ monitor_index ] . mon_window_x < 120 ? 120 : monitor_settings [ monitor_index ] . mon_window_x ,
2022-11-19 08:49:04 -05:00
monitor_settings [ monitor_index ] . mon_window_y < 120 ? 120 : monitor_settings [ monitor_index ] . mon_window_y ,
monitor_settings [ monitor_index ] . mon_window_w > 2048 ? 2048 : monitor_settings [ monitor_index ] . mon_window_w ,
monitor_settings [ monitor_index ] . mon_window_h > 2048 ? 2048 : monitor_settings [ monitor_index ] . mon_window_h ) ;
2022-07-10 11:41:02 +06:00
}
2024-05-03 17:02:13 +02:00
secondaryRenderer - > switchRenderer ( static_cast < RendererStack : : Renderer > ( vid_api ) ) ;
ui - > stackedWidget - > switchRenderer ( static_cast < RendererStack : : Renderer > ( vid_api ) ) ;
2022-07-10 11:41:02 +06:00
}
} else {
for ( int monitor_index = 1 ; monitor_index < MONITORS_NUM ; monitor_index + + ) {
2022-11-19 08:49:04 -05:00
auto & secondaryRenderer = renderers [ monitor_index ] ;
if ( ! renderers [ monitor_index ] )
continue ;
2022-07-10 11:41:02 +06:00
secondaryRenderer - > hide ( ) ;
if ( window_remember & & renderers [ monitor_index ] ) {
monitor_settings [ monitor_index ] . mon_window_w = renderers [ monitor_index ] - > geometry ( ) . width ( ) ;
monitor_settings [ monitor_index ] . mon_window_h = renderers [ monitor_index ] - > geometry ( ) . height ( ) ;
monitor_settings [ monitor_index ] . mon_window_x = renderers [ monitor_index ] - > geometry ( ) . x ( ) ;
monitor_settings [ monitor_index ] . mon_window_y = renderers [ monitor_index ] - > geometry ( ) . y ( ) ;
}
}
}
}
2022-11-19 08:49:04 -05:00
void
MainWindow : : on_actionOpen_screenshots_folder_triggered ( )
2022-08-09 15:35:32 +06:00
{
2024-05-03 17:02:13 +02:00
static_cast < void > ( QDir ( QString ( usr_path ) + QString ( " /screenshots/ " ) ) . mkpath ( " . " ) ) ;
2022-08-09 15:35:32 +06:00
QDesktopServices : : openUrl ( QUrl ( QString ( " file:/// " ) + usr_path + QString ( " /screenshots/ " ) ) ) ;
}
2025-08-12 22:48:22 -04:00
void
MainWindow : : on_actionOpen_printer_tray_triggered ( )
{
static_cast < void > ( QDir ( QString ( usr_path ) + QString ( " /printer/ " ) ) . mkpath ( " . " ) ) ;
QDesktopServices : : openUrl ( QUrl ( QString ( " file:/// " ) + usr_path + QString ( " /printer/ " ) ) ) ;
}
2022-11-19 08:49:04 -05:00
void
MainWindow : : on_actionApply_fullscreen_stretch_mode_when_maximized_triggered ( bool checked )
2022-08-10 01:27:54 +06:00
{
video_fullscreen_scale_maximized = checked ;
2024-05-03 17:02:13 +02:00
const auto widget = ui - > stackedWidget - > currentWidget ( ) ;
2022-08-10 01:27:54 +06:00
ui - > stackedWidget - > onResize ( widget - > width ( ) , widget - > height ( ) ) ;
for ( int i = 1 ; i < MONITORS_NUM ; i + + ) {
2022-11-19 08:49:04 -05:00
if ( renderers [ i ] )
renderers [ i ] - > onResize ( renderers [ i ] - > width ( ) , renderers [ i ] - > height ( ) ) ;
2022-08-10 01:27:54 +06:00
}
device_force_redraw ( ) ;
config_save ( ) ;
}
2023-01-03 15:42:57 +06:00
void MainWindow : : on_actionCursor_Puck_triggered ( )
{
tablet_tool_type = 0 ;
config_save ( ) ;
}
void MainWindow : : on_actionPen_triggered ( )
{
tablet_tool_type = 1 ;
config_save ( ) ;
2023-02-07 17:18:12 +06:00
}
2023-01-03 15:42:57 +06:00
2023-02-06 01:39:34 +06:00
void MainWindow : : on_actionACPI_Shutdown_triggered ( )
{
acpi_pwrbut_pressed = 1 ;
2022-02-03 16:55:32 +06:00
}
2025-08-21 02:32:36 +06:00
void MainWindow : : on_actionCGA_composite_settings_triggered ( )
{
isNonPause = true ;
CGASettingsDialog dialog ;
dialog . setModal ( true ) ;
dialog . exec ( ) ;
isNonPause = false ;
config_save ( ) ;
}