mirror of
https://git.citron-emu.org/citron/emulator
synced 2025-12-19 10:43:33 +00:00
refactor: Exit Fullscreen & Mouse Panning Hotkeys to GRenderWindow
Signed-off-by: Collecting <collecting@noreply.localhost>
This commit is contained in:
@@ -284,13 +284,14 @@ struct NullRenderWidget : public RenderWidget {
|
|||||||
|
|
||||||
GRenderWindow::GRenderWindow(GMainWindow* parent, EmuThread* emu_thread_,
|
GRenderWindow::GRenderWindow(GMainWindow* parent, EmuThread* emu_thread_,
|
||||||
std::shared_ptr<InputCommon::InputSubsystem> input_subsystem_,
|
std::shared_ptr<InputCommon::InputSubsystem> input_subsystem_,
|
||||||
Core::System& system_)
|
Core::System& system_, HotkeyRegistry& hotkey_registry_)
|
||||||
: QWidget(parent),
|
: QWidget(parent),
|
||||||
emu_thread(emu_thread_), input_subsystem{std::move(input_subsystem_)}, system{system_} {
|
emu_thread(emu_thread_), input_subsystem{std::move(input_subsystem_)}, system{system_},
|
||||||
|
hotkey_registry{hotkey_registry_} {
|
||||||
setWindowTitle(QStringLiteral("citron %1 | %2-%3")
|
setWindowTitle(QStringLiteral("citron %1 | %2-%3")
|
||||||
.arg(QString::fromUtf8(Common::g_build_name),
|
.arg(QString::fromUtf8(Common::g_build_name),
|
||||||
QString::fromUtf8(Common::g_scm_branch),
|
QString::fromUtf8(Common::g_scm_branch),
|
||||||
QString::fromUtf8(Common::g_scm_desc)));
|
QString::fromUtf8(Common::g_scm_desc)));
|
||||||
setAttribute(Qt::WA_AcceptTouchEvents);
|
setAttribute(Qt::WA_AcceptTouchEvents);
|
||||||
auto* layout = new QHBoxLayout(this);
|
auto* layout = new QHBoxLayout(this);
|
||||||
layout->setContentsMargins(0, 0, 0, 0);
|
layout->setContentsMargins(0, 0, 0, 0);
|
||||||
@@ -299,7 +300,7 @@ GRenderWindow::GRenderWindow(GMainWindow* parent, EmuThread* emu_thread_,
|
|||||||
this->setMouseTracking(true);
|
this->setMouseTracking(true);
|
||||||
|
|
||||||
strict_context_required = QGuiApplication::platformName() == QStringLiteral("wayland") ||
|
strict_context_required = QGuiApplication::platformName() == QStringLiteral("wayland") ||
|
||||||
QGuiApplication::platformName() == QStringLiteral("wayland-egl");
|
QGuiApplication::platformName() == QStringLiteral("wayland-egl");
|
||||||
|
|
||||||
connect(this, &GRenderWindow::FirstFrameDisplayed, parent, &GMainWindow::OnLoadComplete);
|
connect(this, &GRenderWindow::FirstFrameDisplayed, parent, &GMainWindow::OnLoadComplete);
|
||||||
connect(this, &GRenderWindow::ExecuteProgramSignal, parent, &GMainWindow::OnExecuteProgram,
|
connect(this, &GRenderWindow::ExecuteProgramSignal, parent, &GMainWindow::OnExecuteProgram,
|
||||||
@@ -310,11 +311,13 @@ GRenderWindow::GRenderWindow(GMainWindow* parent, EmuThread* emu_thread_,
|
|||||||
mouse_constrain_timer.setInterval(default_mouse_constrain_timeout);
|
mouse_constrain_timer.setInterval(default_mouse_constrain_timeout);
|
||||||
connect(&mouse_constrain_timer, &QTimer::timeout, this, &GRenderWindow::ConstrainMouse);
|
connect(&mouse_constrain_timer, &QTimer::timeout, this, &GRenderWindow::ConstrainMouse);
|
||||||
|
|
||||||
// mouse-hiding logic for Wayland
|
|
||||||
constexpr int default_mouse_hide_timeout = 2500; // 2.5 seconds
|
constexpr int default_mouse_hide_timeout = 2500; // 2.5 seconds
|
||||||
mouse_hide_timer.setInterval(default_mouse_hide_timeout);
|
mouse_hide_timer.setInterval(default_mouse_hide_timeout);
|
||||||
mouse_hide_timer.setSingleShot(true); // The timer fires only once per start()
|
mouse_hide_timer.setSingleShot(true); // The timer fires only once per start()
|
||||||
connect(&mouse_hide_timer, &QTimer::timeout, this, &GRenderWindow::HideMouseCursor);
|
connect(&mouse_hide_timer, &QTimer::timeout, this, &GRenderWindow::HideMouseCursor);
|
||||||
|
connect(this, &GRenderWindow::PanningToggleHotkeyPressed, this, [this]() {
|
||||||
|
SetMousePanningState(!Settings::values.mouse_panning.GetValue());
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void GRenderWindow::ExecuteProgram(std::size_t program_index) {
|
void GRenderWindow::ExecuteProgram(std::size_t program_index) {
|
||||||
@@ -599,22 +602,31 @@ int GRenderWindow::QtModifierToSwitchModifier(Qt::KeyboardModifiers qt_modifiers
|
|||||||
}
|
}
|
||||||
|
|
||||||
void GRenderWindow::keyPressEvent(QKeyEvent* event) {
|
void GRenderWindow::keyPressEvent(QKeyEvent* event) {
|
||||||
/**
|
if (event->isAutoRepeat()) {
|
||||||
* This feature can be enhanced with the following functions, but they do not provide
|
return; // Ignore auto-repeated key presses
|
||||||
* cross-platform behavior.
|
|
||||||
*
|
|
||||||
* event->nativeVirtualKey() can distinguish between keys on the numpad.
|
|
||||||
* event->nativeModifiers() can distinguish between left and right keys and numlock,
|
|
||||||
* capslock, scroll lock.
|
|
||||||
*/
|
|
||||||
if (!event->isAutoRepeat()) {
|
|
||||||
const auto modifier = QtModifierToSwitchModifier(event->modifiers());
|
|
||||||
const auto key = QtKeyToSwitchKey(Qt::Key(event->key()));
|
|
||||||
input_subsystem->GetKeyboard()->SetKeyboardModifiers(modifier);
|
|
||||||
input_subsystem->GetKeyboard()->PressKeyboardKey(key);
|
|
||||||
// This is used for gamepads that can have any key mapped
|
|
||||||
input_subsystem->GetKeyboard()->PressKey(event->key());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const QKeySequence key_sequence(event->modifiers() | event->key());
|
||||||
|
static const std::string main_window_id = "Main Window";
|
||||||
|
|
||||||
|
if (key_sequence == hotkey_registry.GetKeySequence(main_window_id, "Toggle Mouse Panning")) {
|
||||||
|
emit PanningToggleHotkeyPressed(); // Signal the main window
|
||||||
|
event->accept(); // Consume the event
|
||||||
|
return; // Stop processing
|
||||||
|
}
|
||||||
|
|
||||||
|
if (key_sequence == hotkey_registry.GetKeySequence(main_window_id, "Exit Fullscreen")) {
|
||||||
|
emit FullscreenExitHotkeyPressed(); // Signal the main window
|
||||||
|
event->accept(); // Consume the event
|
||||||
|
return; // Stop processing
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- If not a critical hotkey, pass to game as normal ---
|
||||||
|
const auto modifier = QtModifierToSwitchModifier(event->modifiers());
|
||||||
|
const auto key = QtKeyToSwitchKey(static_cast<Qt::Key>(event->key()));
|
||||||
|
input_subsystem->GetKeyboard()->SetKeyboardModifiers(modifier);
|
||||||
|
input_subsystem->GetKeyboard()->PressKeyboardKey(key);
|
||||||
|
input_subsystem->GetKeyboard()->PressKey(event->key());
|
||||||
}
|
}
|
||||||
|
|
||||||
void GRenderWindow::keyReleaseEvent(QKeyEvent* event) {
|
void GRenderWindow::keyReleaseEvent(QKeyEvent* event) {
|
||||||
@@ -1173,15 +1185,19 @@ void GRenderWindow::showEvent(QShowEvent* event) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool GRenderWindow::eventFilter(QObject* object, QEvent* event) {
|
bool GRenderWindow::eventFilter(QObject* object, QEvent* event) {
|
||||||
|
// Only handle HoverMove for panning.
|
||||||
if (event->type() == QEvent::HoverMove) {
|
if (event->type() == QEvent::HoverMove) {
|
||||||
if (Settings::values.mouse_panning || Settings::values.mouse_enabled) {
|
if (Settings::values.mouse_panning.GetValue() || Settings::values.mouse_enabled.GetValue()) {
|
||||||
auto* hover_event = static_cast<QMouseEvent*>(event);
|
auto* hover_event = static_cast<QMouseEvent*>(event);
|
||||||
mouseMoveEvent(hover_event);
|
mouseMoveEvent(hover_event);
|
||||||
return false;
|
// Consume the hover event to prevent it from being processed twice.
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
emit MouseActivity();
|
emit MouseActivity();
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
|
// Pass on all other events for default processing.
|
||||||
|
return QWidget::eventFilter(object, event);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GRenderWindow::HideMouseCursor() {
|
void GRenderWindow::HideMouseCursor() {
|
||||||
@@ -1189,3 +1205,15 @@ void GRenderWindow::HideMouseCursor() {
|
|||||||
QApplication::setOverrideCursor(QCursor(Qt::BlankCursor));
|
QApplication::setOverrideCursor(QCursor(Qt::BlankCursor));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GRenderWindow::SetMousePanningState(bool enabled) {
|
||||||
|
Settings::values.mouse_panning = enabled;
|
||||||
|
if (enabled) {
|
||||||
|
installEventFilter(this);
|
||||||
|
setAttribute(Qt::WA_Hover, true);
|
||||||
|
} else {
|
||||||
|
QApplication::restoreOverrideCursor();
|
||||||
|
removeEventFilter(this);
|
||||||
|
setAttribute(Qt::WA_Hover, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user