1
0
forked from BRT/arc
arc/views/scrcpy/ScrcpyWindow.cpp
slava c3fed927fc Remove macOS-specific Scrcpy embedding and cleanup debug logs
Removed Scrcpy embedding code and related configurations for macOS. Commented out excessive debug logging in multiple files to reduce console noise. Simplified CMakeLists.txt by unifying platform-specific sections for improved build system clarity.
2025-04-26 15:16:42 +07:00

170 lines
5.3 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "ScrcpyWindow.h"
#include <QScreen>
#include <QDebug>
#include <QGuiApplication>
#include <QTimer>
#include <QCloseEvent>
#include <QThread>
#ifdef Q_OS_WIN
#include <windows.h>
#include <windowsx.h>
#endif
ScrcpyWindow::ScrcpyWindow(QWidget *parent) : QWidget(parent), m_process(nullptr) {
// setWindowFlag(Qt::WindowStaysOnTopHint);
startScrcpy();
}
ScrcpyWindow::~ScrcpyWindow() {
stopScrcpy();
}
void ScrcpyWindow::closeEvent(QCloseEvent *event) {
qDebug() << "closeEvent triggered";
stopScrcpy();
event->accept();
}
void ScrcpyWindow::startScrcpy() {
int deviceWidth = 720;
int deviceHeight = 1600;
QScreen *screen = QGuiApplication::primaryScreen();
int screenHeight = screen->availableGeometry().height();
int screenWidth = screen->availableGeometry().width();
// Вычисляем масштаб так, чтобы устройство влезло в экран (и по ширине, и по высоте)
double scaleW = static_cast<double>(screenWidth) / deviceWidth;
double scaleH = static_cast<double>(screenHeight) / deviceHeight;
double scale = qMin(scaleW, scaleH) * 0.8; // 90% от доступного размера, с отступами
int windowWidth = static_cast<int>(deviceWidth * scale);
int windowHeight = static_cast<int>(deviceHeight * scale);
setFixedSize(windowWidth + 100, windowHeight);
// setWindowFlags(windowFlags() | Qt::MSWindowsFixedSizeDialogHint);
m_process = new QProcess(this);
m_process->start("scrcpy", {"--window-title", "scrcpy", "--always-on-top", "--window-borderless"});
embedPlatformSpecific();
}
void ScrcpyWindow::stopScrcpy() {
m_process->kill(); // Принудительное завершение процесса
delete m_process;
m_process = nullptr;
#ifdef Q_OS_WIN
HWND hwndScrcpy = FindWindowW(nullptr, L"scrcpy");
if (hwndScrcpy) {
PostMessage(hwndScrcpy, WM_CLOSE, 0, 0);
}
#endif
}
#ifdef Q_OS_WIN
LRESULT CALLBACK wndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
OutputDebugString(L"WM_CLOSE received\n");
HWND hwndScrcpy = FindWindowW(nullptr, L"scrcpy");
if (!hwndScrcpy)
return DefWindowProc(hwnd, msg, wParam, lParam);
if (msg == WM_CLOSE) {
qDebug() << "WM_CLOSE received, closing scrcpy window.";
// Возможно, необходимо обработать конкретно это сообщение
// или сделать дополнительные проверки.
}
switch (msg) {
case WM_LBUTTONDOWN:
case WM_LBUTTONUP:
case WM_MOUSEMOVE:
case WM_RBUTTONDOWN:
case WM_RBUTTONUP:
case WM_MBUTTONDOWN:
case WM_MBUTTONUP:
case WM_MOUSEWHEEL:
{
// Перевод координат мыши в координаты окна scrcpy
POINT pt;
pt.x = GET_X_LPARAM(lParam);
pt.y = GET_Y_LPARAM(lParam);
qDebug() << "Before ClientToScreen: " << pt.x << ", " << pt.y;
ClientToScreen(hwnd, &pt);
qDebug() << "After ClientToScreen: " << pt.x << ", " << pt.y;
ScreenToClient(hwndScrcpy, &pt);
qDebug() << "After ScreenToClient: " << pt.x << ", " << pt.y;
LPARAM newLParam = MAKELPARAM(pt.x, pt.y);
SendMessage(hwndScrcpy, msg, wParam, newLParam);
return 0;
}
case WM_KEYDOWN:
case WM_KEYUP:
case WM_CHAR:
SendMessage(hwndScrcpy, msg, wParam, lParam);
return 0;
}
return DefWindowProc(hwnd, msg, wParam, lParam);
}
void ScrcpyWindow::embedPlatformSpecific() {
HWND hwndScrcpy = FindWindowW(nullptr, L"scrcpy");
int attempts = 0;
while (!hwndScrcpy && attempts < 20) {
hwndScrcpy = FindWindowW(nullptr, L"scrcpy");
Sleep(100); // Задержка 100 мс
attempts++;
}
if (!hwndScrcpy) {
qDebug() << "scrcpy window not found";
return;
}
Sleep(1000);
// Получаем hwnd текущего окна
HWND hwndTarget = (HWND)this->winId();
// Устанавливаем окно scrcpy как дочернее
SetParent(hwndScrcpy, hwndTarget);
// Убираем рамки и заголовок
LONG style = GetWindowLong(hwndScrcpy, GWL_STYLE);
style &= ~(WS_CAPTION | WS_THICKFRAME | WS_BORDER);
SetWindowLong(hwndScrcpy, GWL_STYLE, style);
// Получаем размеры клиентской области
RECT rect;
GetClientRect(hwndTarget, &rect);
qDebug() << "Client area size: " << rect.right << ", " << rect.bottom;
// int deviceWidth = 720;
// int deviceHeight = 1600;
// Client area size: 676 , 1502
// Получаем размеры клиентской области
// RECT rect;
// GetClientRect(hwndTarget, &rect);
SetWindowPos(hwndScrcpy, HWND_TOP, 0, 0,
rect.right - rect.left - 200, rect.bottom - rect.top,
SWP_SHOWWINDOW | SWP_FRAMECHANGED);
// rect.right - rect.left, rect.bottom - rect.top,
// Сохраняем старую оконную процедуру
// LONG_PTR prevWndProc = GetWindowLongPtr(hwndTarget, GWLP_WNDPROC);
// SetWindowLongPtr(hwndTarget, GWLP_WNDPROC, (LONG_PTR)wndProc);
}
#endif