Add ScrcpyWindow integration for screen mirroring
Introduced a ScrcpyWindow to enable integration of the scrcpy tool for device screen mirroring within the application. Platform-specific embedding is supported for macOS and Windows, with structure adjustments made in MainWindow and the build system (CMakeLists.txt).
This commit is contained in:
parent
c1b34ce7d7
commit
327b206fe8
@ -19,8 +19,15 @@ elseif (APPLE)
|
||||
set(CMAKE_PREFIX_PATH "/opt/homebrew/opt/qt")
|
||||
include_directories("/opt/homebrew/opt/tesseract/include")
|
||||
link_directories("/opt/homebrew/opt/tesseract/lib")
|
||||
|
||||
set(CMAKE_CXX_STANDARD 17) # или 20, если нужно
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ObjC++")
|
||||
endif ()
|
||||
|
||||
set(SCRCPY
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/views/scrcpy/ScrcpyWindow_mac.mm
|
||||
)
|
||||
|
||||
find_package(Qt6 REQUIRED COMPONENTS
|
||||
Widgets
|
||||
Sql
|
||||
@ -52,6 +59,7 @@ add_executable(ARCDesktopProject
|
||||
${SERVICES_SOURCES}
|
||||
${DB_SOURCES}
|
||||
${MODELS_SOURCES}
|
||||
${SCRCPY}
|
||||
)
|
||||
|
||||
if (WIN32)
|
||||
|
||||
Binary file not shown.
@ -48,6 +48,9 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) {
|
||||
stackedWidget->setCurrentWidget(accountPage);
|
||||
deleteDevicePage(); // освобождаем ресурсы
|
||||
});
|
||||
|
||||
scrcpyWindow = new ScrcpyWindow();
|
||||
scrcpyWindow->show();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -4,6 +4,7 @@
|
||||
#include <QStackedWidget>
|
||||
#include <QTimer>
|
||||
#include "db/DeviceInfo.h"
|
||||
#include "scrcpy/ScrcpyWindow.h"
|
||||
#include "widget/FlowLayout.h"
|
||||
|
||||
class MainWindow final : public QMainWindow {
|
||||
@ -21,6 +22,8 @@ private:
|
||||
QWidget* devicePage = nullptr;
|
||||
QWidget* accountPage = nullptr;
|
||||
|
||||
ScrcpyWindow *scrcpyWindow;
|
||||
|
||||
void createDevicePage();
|
||||
void deleteDevicePage();
|
||||
};
|
||||
|
||||
68
views/scrcpy/ScrcpyWindow.cpp
Normal file
68
views/scrcpy/ScrcpyWindow.cpp
Normal file
@ -0,0 +1,68 @@
|
||||
#include "ScrcpyWindow.h"
|
||||
#include <QDebug>
|
||||
#include <QTimer>
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
ScrcpyWindow::ScrcpyWindow(QWidget *parent) : QWidget(parent), m_process(nullptr) {
|
||||
setWindowFlag(Qt::WindowStaysOnTopHint);
|
||||
startScrcpy();
|
||||
}
|
||||
|
||||
ScrcpyWindow::~ScrcpyWindow() {
|
||||
stopScrcpy();
|
||||
}
|
||||
|
||||
void ScrcpyWindow::startScrcpy() {
|
||||
m_process = new QProcess(this);
|
||||
m_process->start("scrcpy", {"--window-title", "scrcpy", "--always-on-top"});
|
||||
|
||||
// Подождём немного, чтобы окно scrcpy запустилось
|
||||
QTimer::singleShot(5000, this, &ScrcpyWindow::embedPlatformSpecific);
|
||||
}
|
||||
|
||||
void ScrcpyWindow::stopScrcpy() {
|
||||
if (m_process) {
|
||||
m_process->terminate();
|
||||
m_process->waitForFinished();
|
||||
delete m_process;
|
||||
m_process = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ScrcpyWindow::embedPlatformSpecific() {
|
||||
#ifdef Q_OS_WIN
|
||||
|
||||
HWND hwndScrcpy = FindWindowW(nullptr, L"scrcpy");
|
||||
if (!hwndScrcpy) {
|
||||
qDebug() << "scrcpy window not found";
|
||||
return;
|
||||
}
|
||||
|
||||
HWND hwndTarget = (HWND)this->winId();
|
||||
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);
|
||||
SetWindowPos(hwndScrcpy, HWND_TOP, 0, 0,
|
||||
rect.right - rect.left, rect.bottom - rect.top,
|
||||
SWP_SHOWWINDOW);
|
||||
|
||||
#elif defined(Q_OS_MAC)
|
||||
|
||||
extern void embedScrcpyMac(QWidget *container);
|
||||
embedScrcpyMac(this);
|
||||
|
||||
#else
|
||||
|
||||
qDebug() << "Scrcpy embedding not implemented for this OS.";
|
||||
|
||||
#endif
|
||||
}
|
||||
22
views/scrcpy/ScrcpyWindow.h
Normal file
22
views/scrcpy/ScrcpyWindow.h
Normal file
@ -0,0 +1,22 @@
|
||||
#pragma once
|
||||
|
||||
#include <QWidget>
|
||||
#include <QProcess>
|
||||
|
||||
class ScrcpyWindow final : public QWidget {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit ScrcpyWindow(QWidget *parent = nullptr);
|
||||
|
||||
~ScrcpyWindow() override;
|
||||
|
||||
private:
|
||||
QProcess *m_process;
|
||||
|
||||
void startScrcpy();
|
||||
|
||||
void stopScrcpy();
|
||||
|
||||
void embedPlatformSpecific();
|
||||
};
|
||||
61
views/scrcpy/ScrcpyWindow_mac.mm
Normal file
61
views/scrcpy/ScrcpyWindow_mac.mm
Normal file
@ -0,0 +1,61 @@
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#import <QtCore/QDebug>
|
||||
#import <ApplicationServices/ApplicationServices.h>
|
||||
#include <QWidget>
|
||||
#include <QWindow>
|
||||
|
||||
void listAllWindows() {
|
||||
CFArrayRef windowList = CGWindowListCopyWindowInfo(kCGWindowListOptionOnScreenOnly, kCGNullWindowID);
|
||||
|
||||
for (NSDictionary *entry in (__bridge NSArray *)windowList) {
|
||||
NSString *name = entry[(NSString *)kCGWindowName];
|
||||
NSString *owner = entry[(NSString *)kCGWindowOwnerName];
|
||||
NSNumber *windowNumber = entry[(NSString *)kCGWindowNumber];
|
||||
if (name.length > 0) {
|
||||
qDebug() << "Window:" << owner.UTF8String << "-" << name.UTF8String
|
||||
<< "ID:" << windowNumber.intValue;
|
||||
}
|
||||
}
|
||||
|
||||
CFRelease(windowList);
|
||||
}
|
||||
|
||||
void embedScrcpyMac(QWidget *container) {
|
||||
// Получаем список окон
|
||||
NSArray *windows = [NSApp windows];
|
||||
NSWindow *scrcpyWindow = nil;
|
||||
|
||||
listAllWindows();
|
||||
|
||||
for (NSWindow *window in windows) {
|
||||
NSString *title = [window title];
|
||||
qDebug() << "Found window title:" << title.UTF8String;
|
||||
|
||||
if ([[window title] isEqualToString:@"scrcpy"]) {
|
||||
scrcpyWindow = window;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!scrcpyWindow) {
|
||||
qDebug() << "scrcpy window not found";
|
||||
return;
|
||||
}
|
||||
|
||||
// Убираем заголовок и рамку
|
||||
[scrcpyWindow setStyleMask:NSWindowStyleMaskBorderless];
|
||||
|
||||
// Получаем координаты окна Qt
|
||||
NSView *nativeView = (NSView *)container->winId();
|
||||
NSWindow *qtWindow = [nativeView window];
|
||||
NSRect frame = [qtWindow frame];
|
||||
|
||||
// Задаём новый размер и позицию для окна scrcpy
|
||||
CGFloat width = frame.size.width;
|
||||
CGFloat height = frame.size.height;
|
||||
CGFloat x = frame.origin.x;
|
||||
CGFloat y = frame.origin.y;
|
||||
|
||||
[scrcpyWindow setFrame:NSMakeRect(x, y, width, height) display:YES];
|
||||
[scrcpyWindow orderFront:nil];
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user