Implement focus-shifting on Windows and waiting status

This commit is contained in:
Cacodemon345
2025-07-11 18:04:58 +06:00
parent bb7ebc72c8
commit 07c6a8a154
11 changed files with 70 additions and 1 deletions

View File

@@ -807,6 +807,9 @@ main(int argc, char *argv[])
});
QObject::connect(main_window, &MainWindow::vmmRunningStateChanged, &manager_socket, &VMManagerClientSocket::clientRunningStateChanged);
main_window->installEventFilter(&manager_socket);
main_window->show();
manager_socket.sendWinIdMessage(main_window->winId());
}
// pc_reset_hard_init();

View File

@@ -218,19 +218,32 @@ VMManagerClientSocket::eventFilter(QObject *obj, QEvent *event)
if (event->type() == QEvent::WindowBlocked) {
running_state = dopause ? VMManagerProtocol::RunningState::PausedWaiting : VMManagerProtocol::RunningState::RunningWaiting;
clientRunningStateChanged(running_state);
window_blocked = true;
} else if (event->type() == QEvent::WindowUnblocked) {
running_state = dopause ? VMManagerProtocol::RunningState::Paused : VMManagerProtocol::RunningState::Running;
clientRunningStateChanged(running_state);
window_blocked = false;
}
}
return QObject::eventFilter(obj, event);
}
void
VMManagerClientSocket::sendWinIdMessage(WId id)
{
QJsonObject extra_object;
extra_object["params"] = static_cast<int>(id);
sendMessageWithObject(VMManagerProtocol::ClientMessage::WinIdMessage, extra_object);
}
void
VMManagerClientSocket::clientRunningStateChanged(VMManagerProtocol::RunningState state) const
{
QJsonObject extra_object;
if ((state == VMManagerProtocol::RunningState::Paused
|| state == VMManagerProtocol::RunningState::Running) && window_blocked) {
state = (state == VMManagerProtocol::RunningState::Paused) ? VMManagerProtocol::RunningState::PausedWaiting : VMManagerProtocol::RunningState::RunningWaiting;
}
extra_object["status"] = static_cast<int>(state);
sendMessageWithObject(VMManagerProtocol::ClientMessage::RunningStateChanged, extra_object);
}

View File

@@ -31,6 +31,8 @@ public:
explicit VMManagerClientSocket(QObject* object = nullptr);
bool IPCConnect(const QString &server);
void sendWinIdMessage(WId id);
signals:
void pause();
void ctrlaltdel();
@@ -47,6 +49,7 @@ private:
QString server_name;
QLocalSocket *socket;
bool server_connected;
bool window_blocked;
void connected() const;
void disconnected() const;
static void connectionError(QLocalSocket::LocalSocketError socketError);

View File

@@ -336,6 +336,17 @@ VMManagerDetails::updateProcessStatus() {
connect(startPauseButton, &QToolButton::clicked, sysconfig, &VMManagerSystem::startButtonPressed);
startPauseButton->setToolTip(tr("Start"));
}
if (sysconfig->window_obscured) {
resetButton->setDisabled(true);
stopButton->setDisabled(true);
cadButton->setDisabled(true);
startPauseButton->setDisabled(true);
configureButton->setDisabled(true);
} else {
configureButton->setDisabled(false);
startPauseButton->setDisabled(false);
}
}
void

View File

@@ -59,6 +59,7 @@ VMManagerMain::VMManagerMain(QWidget *parent) :
connect(&nameChangeAction, &QAction::triggered, ui->listView, [this, indexAt] {
updateDisplayName(indexAt);
});
nameChangeAction.setEnabled(!selected_sysconfig->window_obscured);
QAction openSystemFolderAction(tr("Open folder"));
contextMenu.addAction(&openSystemFolderAction);
@@ -82,6 +83,7 @@ VMManagerMain::VMManagerMain(QWidget *parent) :
selected_sysconfig->setIcon(iconName);
}
});
setSystemIcon.setEnabled(!selected_sysconfig->window_obscured);
contextMenu.addSeparator();

View File

@@ -91,6 +91,8 @@ VMManagerProtocol::getClientMessageType(const QJsonObject &json_document)
return VMManagerProtocol::ClientMessage::WindowUnblocked;
} else if (message_type == "RunningStateChanged") {
return VMManagerProtocol::ClientMessage::RunningStateChanged;
} else if (message_type == "WinIdMessage") {
return VMManagerProtocol::ClientMessage::WinIdMessage;
}
return VMManagerProtocol::ClientMessage::UnknownMessage;
}

View File

@@ -54,6 +54,7 @@ public:
WindowBlocked,
WindowUnblocked,
RunningStateChanged,
WinIdMessage,
UnknownMessage,
};
Q_ENUM(ClientMessage);
@@ -82,6 +83,7 @@ public:
static bool hasRequiredFields(const QJsonObject &json_document);
static QJsonObject getParams(const QJsonObject &json_document);
static QJsonObject getStatus(const QJsonObject &json_document);
static ClientMessage getClientMessageType(const QJsonObject &json_document);
static ManagerMessage getManagerMessageType(const QJsonObject &json_document);

View File

@@ -153,6 +153,16 @@ VMManagerServerSocket::jsonReceived(const QJsonObject &json)
auto message_type = VMManagerProtocol::getClientMessageType(json);
switch (message_type) {
case VMManagerProtocol::ClientMessage::WinIdMessage:
qDebug("WinId message received from client");
params_object = VMManagerProtocol::getParams(json);
if (!params_object.isEmpty()) {
// valid object
if(params_object.value("params").type() == QJsonValue::Double) {
emit winIdReceived(params_object.value("params").toVariant().toULongLong());
}
}
break;
case VMManagerProtocol::ClientMessage::Status:
qDebug("Status message received from client");
break;

View File

@@ -75,6 +75,7 @@ signals:
void dataReceived();
void windowStatusChanged(int status);
void runningStatusChanged(VMManagerProtocol::RunningState state);
void winIdReceived(WId id);
};

View File

@@ -15,6 +15,7 @@
* Copyright 2024 cold-brewed
*/
#include <QString>
#include <QDirIterator>
#include <QDebug>
@@ -26,10 +27,15 @@
#include <QtNetwork>
#include <QElapsedTimer>
#include <QProgressDialog>
#include <QWindow>
#include "qt_vmmanager_system.hpp"
// #include "qt_vmmanager_details_section.hpp"
#include "qt_vmmanager_detailsection.hpp"
#ifdef Q_OS_WINDOWS
#include <windows.h>
#endif
extern "C" {
#include <86box/86box.h>
@@ -427,6 +433,11 @@ VMManagerSystem::launchSettings() {
// If the system is already running, instruct it to show settings
if (process->processId() != 0) {
#ifdef Q_OS_WINDOWS
if (this->id) {
SetForegroundWindow((HWND)this->id);
}
#endif
socket_server->serverSendMessage(VMManagerProtocol::ManagerMessage::ShowSettings);
return;
}
@@ -776,6 +787,7 @@ VMManagerSystem::startServer() {
connect(socket_server, &VMManagerServerSocket::dataReceived, this, &VMManagerSystem::dataReceived);
connect(socket_server, &VMManagerServerSocket::windowStatusChanged, this, &VMManagerSystem::windowStatusChangeReceived);
connect(socket_server, &VMManagerServerSocket::runningStatusChanged, this, &VMManagerSystem::runningStatusChangeReceived);
connect(socket_server, &VMManagerServerSocket::winIdReceived, this, [this] (WId id) { this->id = id; });
return true;
} else {
return false;
@@ -892,12 +904,20 @@ VMManagerSystem::runningStatusChangeReceived(VMManagerProtocol::RunningState sta
{
if(state == VMManagerProtocol::RunningState::Running) {
process_status = VMManagerSystem::ProcessStatus::Running;
window_obscured = false;
windowStatusChanged();
} else if(state == VMManagerProtocol::RunningState::Paused) {
process_status = VMManagerSystem::ProcessStatus::Paused;
window_obscured = false;
windowStatusChanged();
} else if(state == VMManagerProtocol::RunningState::RunningWaiting) {
process_status = VMManagerSystem::ProcessStatus::RunningWaiting;
window_obscured = true;
windowStatusChanged();
} else if(state == VMManagerProtocol::RunningState::PausedWaiting) {
process_status = VMManagerSystem::ProcessStatus::PausedWaiting;
window_obscured = true;
windowStatusChanged();
} else {
process_status = VMManagerSystem::ProcessStatus::Unknown;
}

View File

@@ -174,6 +174,8 @@ private:
// Configuration file settings
VMManagerConfig *config_settings;
WId id;
bool serverIsRunning;
bool startServer();