mirror of
https://github.com/barry-ran/QtScrcpy.git
synced 2025-04-20 11:35:56 +00:00
feat: good framelesswindow for mac
This commit is contained in:
parent
1e15a305e7
commit
80851675f2
16 changed files with 460 additions and 93 deletions
|
@ -11,7 +11,7 @@
|
|||
#include "dialog.h"
|
||||
#include "mousetap/mousetap.h"
|
||||
#include "stream.h"
|
||||
#include "windowframelesshelper.h"
|
||||
#include "windowframelesshelper/windowframelesshelper.h"
|
||||
|
||||
static Dialog *g_mainDlg = Q_NULLPTR;
|
||||
|
||||
|
|
|
@ -2,24 +2,22 @@ FORMS +=
|
|||
|
||||
HEADERS += \
|
||||
$$PWD/keepratiowidget.h \
|
||||
$$PWD/magneticwidget.h \
|
||||
$$PWD/windowframelesshelper.h \
|
||||
$$PWD/windownativeeventfilter.h
|
||||
|
||||
$$PWD/magneticwidget.h
|
||||
|
||||
SOURCES += \
|
||||
$$PWD/keepratiowidget.cpp \
|
||||
$$PWD/magneticwidget.cpp \
|
||||
$$PWD/windownativeeventfilter.cpp
|
||||
$$PWD/magneticwidget.cpp
|
||||
|
||||
win32 {
|
||||
SOURCES += $$PWD/windowframelesshelper.cpp
|
||||
SOURCES +=
|
||||
}
|
||||
|
||||
mac {
|
||||
SOURCES += $$PWD/windowframelesshelper.mm
|
||||
SOURCES +=
|
||||
}
|
||||
|
||||
linux {
|
||||
SOURCES += $$PWD/windowframelesshelper.cpp
|
||||
SOURCES +=
|
||||
}
|
||||
|
||||
include ($$PWD/windowframelesshelper/windowframelesshelper.pri)
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
#include "nativewindowutils.h"
|
||||
|
||||
quint64 NativeWindowUtils::GetHandleByWId(WId id) {
|
||||
return (quint64)id;
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
#pragma once
|
||||
#include <QWindow>
|
||||
|
||||
class NativeWindowUtils
|
||||
{
|
||||
public:
|
||||
static quint64 GetHandleByWId(WId id);
|
||||
};
|
15
QtScrcpy/uibase/windowframelesshelper/nativewindowutils.mm
Normal file
15
QtScrcpy/uibase/windowframelesshelper/nativewindowutils.mm
Normal file
|
@ -0,0 +1,15 @@
|
|||
#include "nativewindowutils.h"
|
||||
#include <Cocoa/Cocoa.h>
|
||||
|
||||
quint64 NativeWindowUtils::GetHandleByWId(WId id) {
|
||||
NSView* view = (NSView*)id;
|
||||
if (nullptr == view) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
NSWindow *window = view.window;
|
||||
if (nullptr == window) {
|
||||
return 0;
|
||||
}
|
||||
return (quint64)window;
|
||||
}
|
|
@ -1,9 +1,17 @@
|
|||
#include "windowframelesshelper.h"
|
||||
#include "windownativeeventfilter.h"
|
||||
#include "windowframelessmanager.h"
|
||||
|
||||
WindowFramelessHelper::WindowFramelessHelper(QObject *parent) : QObject(parent)
|
||||
{
|
||||
WindowFramelessManager::Instance()->addWindow(this);
|
||||
#ifdef Q_OS_WIN32
|
||||
WindowNativeEventFilter::Instance()->Init();
|
||||
#endif
|
||||
}
|
||||
|
||||
WindowFramelessHelper::~WindowFramelessHelper()
|
||||
{
|
||||
WindowFramelessManager::Instance()->removeWindow(this);
|
||||
}
|
||||
|
||||
QQuickWindow *WindowFramelessHelper::target() const
|
||||
|
@ -13,18 +21,10 @@ QQuickWindow *WindowFramelessHelper::target() const
|
|||
|
||||
void WindowFramelessHelper::setTarget(QQuickWindow *target)
|
||||
{
|
||||
if (target == m_target) {
|
||||
if (target == nullptr || target == m_target) {
|
||||
return;
|
||||
}
|
||||
m_target = target;
|
||||
|
||||
#ifdef Q_OS_WIN32
|
||||
WindowNativeEventFilter::Instance()->Init();
|
||||
#endif
|
||||
|
||||
emit targetChanged();
|
||||
}
|
||||
|
||||
void WindowFramelessHelper::updateStyle() {
|
||||
|
||||
}
|
|
@ -1,5 +1,4 @@
|
|||
#ifndef WindowFramelessHelper_H
|
||||
#define WindowFramelessHelper_H
|
||||
#pragma once
|
||||
|
||||
#include <QQuickWindow>
|
||||
|
||||
|
@ -10,18 +9,14 @@ class WindowFramelessHelper : public QObject
|
|||
|
||||
public:
|
||||
explicit WindowFramelessHelper(QObject *parent = nullptr);
|
||||
virtual ~WindowFramelessHelper();
|
||||
|
||||
QQuickWindow *target() const;
|
||||
void setTarget(QQuickWindow *target);
|
||||
|
||||
protected:
|
||||
void updateStyle();
|
||||
|
||||
signals:
|
||||
void targetChanged();
|
||||
|
||||
private:
|
||||
QQuickWindow* m_target = nullptr;
|
||||
};
|
||||
|
||||
#endif // WindowFramelessHelper_H
|
|
@ -0,0 +1,24 @@
|
|||
HEADERS += \
|
||||
$$PWD/nativewindowutils.h \
|
||||
$$PWD/windowframelesshelper.h \
|
||||
$$PWD/windowframelessmanager.h
|
||||
|
||||
SOURCES += \
|
||||
$$PWD/windowframelesshelper.cpp \
|
||||
$$PWD/windowframelessmanager.cpp
|
||||
|
||||
win32 {
|
||||
HEADERS += $$PWD/windownativeeventfilterwin.h
|
||||
SOURCES += $$PWD/windownativeeventfilterwin.cpp \
|
||||
$$PWD/nativewindowutils.cpp \
|
||||
}
|
||||
|
||||
mac {
|
||||
HEADERS += $$PWD/windownativeeventfiltermac.h
|
||||
SOURCES += $$PWD/windownativeeventfiltermac.mm \
|
||||
$$PWD/nativewindowutils.mm
|
||||
}
|
||||
|
||||
linux {
|
||||
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
#include "windowframelessmanager.h"
|
||||
#include "windowframelesshelper.h"
|
||||
#include "nativewindowutils.h"
|
||||
|
||||
static QVector<WindowFramelessHelper*> s_windowFramelessHelpers;
|
||||
|
||||
WindowFramelessManager::WindowFramelessManager()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
WindowFramelessManager::~WindowFramelessManager()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
WindowFramelessManager *WindowFramelessManager::Instance()
|
||||
{
|
||||
static WindowFramelessManager windowNativeEventFilter;
|
||||
return &windowNativeEventFilter;
|
||||
}
|
||||
|
||||
void WindowFramelessManager::addWindow(WindowFramelessHelper* win)
|
||||
{
|
||||
if (nullptr == win) {
|
||||
return;
|
||||
}
|
||||
s_windowFramelessHelpers.push_back(win);
|
||||
}
|
||||
|
||||
void WindowFramelessManager::removeWindow(WindowFramelessHelper* win)
|
||||
{
|
||||
if (nullptr == win) {
|
||||
return;
|
||||
}
|
||||
s_windowFramelessHelpers.removeOne(win);
|
||||
}
|
||||
|
||||
WindowFramelessHelper* WindowFramelessManager::getWindowByHandle(quint64 handle)
|
||||
{
|
||||
quint64 targetHandle = 0;
|
||||
for (auto i = s_windowFramelessHelpers.begin(); i != s_windowFramelessHelpers.end(); i++) {
|
||||
if ((*i)->target() == nullptr) {
|
||||
continue;
|
||||
}
|
||||
|
||||
targetHandle = NativeWindowUtils::GetHandleByWId((*i)->target()->winId());
|
||||
if (targetHandle == handle) {
|
||||
return (*i);
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
#pragma once
|
||||
#include <QQuickWindow>
|
||||
#include <QVector>
|
||||
|
||||
class WindowFramelessHelper;
|
||||
class WindowFramelessManager
|
||||
{
|
||||
private:
|
||||
WindowFramelessManager();
|
||||
|
||||
public:
|
||||
virtual ~WindowFramelessManager();
|
||||
|
||||
public:
|
||||
static WindowFramelessManager* Instance();
|
||||
|
||||
void addWindow(WindowFramelessHelper* win);
|
||||
void removeWindow(WindowFramelessHelper* win);
|
||||
WindowFramelessHelper* getWindowByHandle(quint64 handle);
|
||||
};
|
|
@ -0,0 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
class windownativeeventfiltermac
|
||||
{
|
||||
public:
|
||||
windownativeeventfiltermac();
|
||||
};
|
|
@ -1,9 +1,15 @@
|
|||
#include "windowframelesshelper.h"
|
||||
#include "windownativeeventfiltermac.h"
|
||||
|
||||
#include <Cocoa/Cocoa.h>
|
||||
#include <QOperatingSystemVersion>
|
||||
#import <objc/runtime.h>
|
||||
#include <QDebug>
|
||||
#include "windowframelessmanager.h"
|
||||
|
||||
windownativeeventfiltermac::windownativeeventfiltermac()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void SwizzleSelector(Class originalCls, SEL originalSelector, Class swizzledCls, SEL swizzledSelector) {
|
||||
Method originalMethod = class_getInstanceMethod(originalCls, originalSelector);
|
||||
|
@ -48,16 +54,20 @@ void SwizzleSelector(Class originalCls, SEL originalSelector, Class swizzledCls,
|
|||
{
|
||||
[self filter_setStyleMask:styleMask];
|
||||
|
||||
//设置标题文字和图标为不可见
|
||||
self.titleVisibility = NSWindowTitleHidden;
|
||||
//设置标题栏为透明
|
||||
self.titlebarAppearsTransparent = YES;
|
||||
//设置不可由标题栏拖动,避免与自定义拖动冲突
|
||||
self.movable = NO;
|
||||
self.hasShadow = YES;
|
||||
//设置view扩展到标题栏
|
||||
if (!(self.styleMask & NSWindowStyleMaskFullSizeContentView)) {
|
||||
self.styleMask |= NSWindowStyleMaskFullSizeContentView;
|
||||
WindowFramelessHelper* win = WindowFramelessManager::Instance()->getWindowByHandle((quint64)self);
|
||||
|
||||
if (win) {
|
||||
//设置标题文字和图标为不可见
|
||||
self.titleVisibility = NSWindowTitleHidden;
|
||||
//设置标题栏为透明
|
||||
self.titlebarAppearsTransparent = YES;
|
||||
//设置不可由标题栏拖动,避免与自定义拖动冲突
|
||||
self.movable = NO;
|
||||
self.hasShadow = YES;
|
||||
//设置view扩展到标题栏
|
||||
if (!(self.styleMask & NSWindowStyleMaskFullSizeContentView)) {
|
||||
self.styleMask |= NSWindowStyleMaskFullSizeContentView;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -66,58 +76,3 @@ void SwizzleSelector(Class originalCls, SEL originalSelector, Class swizzledCls,
|
|||
[self filter_setTitlebarAppearsTransparent:titlebarAppearsTransparent];
|
||||
}
|
||||
@end
|
||||
|
||||
WindowFramelessHelper::WindowFramelessHelper(QObject *parent) : QObject(parent)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
QQuickWindow *WindowFramelessHelper::target() const
|
||||
{
|
||||
return m_target;
|
||||
}
|
||||
|
||||
void WindowFramelessHelper::setTarget(QQuickWindow *target)
|
||||
{
|
||||
if (target == m_target) {
|
||||
return;
|
||||
}
|
||||
m_target = target;
|
||||
|
||||
//updateStyle();
|
||||
|
||||
emit targetChanged();
|
||||
}
|
||||
/*
|
||||
void WindowFramelessHelper::updateStyle() {
|
||||
if (!m_target) {
|
||||
return;
|
||||
}
|
||||
|
||||
//如果当前osx版本老于10.9,则后续代码不可用。转为使用定制的系统按钮,不支持自由缩放窗口及窗口阴影
|
||||
if (QOperatingSystemVersion::current() < QOperatingSystemVersion::OSXYosemite) {
|
||||
return;
|
||||
}
|
||||
|
||||
NSView* view = (NSView*)m_target->winId();
|
||||
if (nullptr == view) {
|
||||
return;
|
||||
}
|
||||
|
||||
NSWindow *window = view.window;
|
||||
if (nullptr == window) {
|
||||
return;
|
||||
}
|
||||
|
||||
//设置标题文字和图标为不可见
|
||||
window.titleVisibility = NSWindowTitleHidden;
|
||||
//设置标题栏为透明
|
||||
window.titlebarAppearsTransparent = YES;
|
||||
//设置不可由标题栏拖动,避免与自定义拖动冲突
|
||||
window.movable = NO;
|
||||
window.hasShadow = YES;
|
||||
//设置view扩展到标题栏
|
||||
window.styleMask |= NSWindowStyleMaskFullSizeContentView;
|
||||
}
|
||||
|
||||
*/
|
254
QtScrcpy/uibase/windownativeeventfilterwin.cpp
Normal file
254
QtScrcpy/uibase/windownativeeventfilterwin.cpp
Normal file
|
@ -0,0 +1,254 @@
|
|||
#include "windownativeeventfilter.h"
|
||||
|
||||
#if defined(Q_OS_WIN)
|
||||
#include <QCursor>
|
||||
#include <QDebug>
|
||||
#include <QGuiApplication>
|
||||
#include <windows.h>
|
||||
#include <windowsx.h>
|
||||
|
||||
WindowNativeEventFilter::WindowNativeEventFilter() {}
|
||||
|
||||
WindowNativeEventFilter::~WindowNativeEventFilter()
|
||||
{
|
||||
// do nothing, because this object is static instance
|
||||
}
|
||||
|
||||
WindowNativeEventFilter *WindowNativeEventFilter::Instance()
|
||||
{
|
||||
static WindowNativeEventFilter g_windowNativeEventFilter;
|
||||
return &g_windowNativeEventFilter;
|
||||
}
|
||||
|
||||
void WindowNativeEventFilter::Init()
|
||||
{
|
||||
if (!m_inited) {
|
||||
m_inited = true;
|
||||
QGuiApplication::instance()->installNativeEventFilter(this);
|
||||
}
|
||||
}
|
||||
|
||||
bool WindowNativeEventFilter::nativeEventFilter(const QByteArray &eventType, void *message, long *result)
|
||||
{
|
||||
Q_UNUSED(eventType);
|
||||
|
||||
MSG *param = static_cast<MSG *>(message);
|
||||
if (!param) {
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (param->message) {
|
||||
case WM_NCHITTEST: {
|
||||
if (processNcHitTest(message, result)) {
|
||||
return true;
|
||||
}
|
||||
} break;
|
||||
case WM_NCLBUTTONDOWN: {
|
||||
if (processNcLButtonDown(message, result)) {
|
||||
return true;
|
||||
}
|
||||
} break;
|
||||
case WM_SETCURSOR: {
|
||||
if (processSetCursor(message, result)) {
|
||||
return true;
|
||||
}
|
||||
} break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool WindowNativeEventFilter::processNcHitTest(void *message, long *result)
|
||||
{
|
||||
MSG *param = static_cast<MSG *>(message);
|
||||
if (!param) {
|
||||
return false;
|
||||
}
|
||||
|
||||
QWindow *window = getWindow((WId)param->hwnd);
|
||||
if (!window) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 没有最大化&全屏按钮,则认为是固定尺寸窗口
|
||||
if (!(window->flags() & Qt::WindowMaximizeButtonHint) && !(window->flags() & Qt::WindowFullscreenButtonHint)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
qreal dpi = window->devicePixelRatio();
|
||||
if (dpi <= 0.99) {
|
||||
dpi = 1.0;
|
||||
}
|
||||
|
||||
QPoint ptCursor = QCursor::pos();
|
||||
int nX = ptCursor.x() - window->geometry().x();
|
||||
int nY = ptCursor.y() - window->geometry().y();
|
||||
|
||||
*result = HTCLIENT;
|
||||
|
||||
if (Qt::WindowMaximized == window->windowState()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((window->windowStates() & Qt::WindowMaximized) || (window->windowStates() & Qt::WindowFullScreen)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
qDebug() << "processNcHitTest:" << ptCursor << window->geometry() << "d:" << nX;
|
||||
int borderWidth = 5;
|
||||
if ((nX > m_windowMargin.left()) && (nX < m_windowMargin.left() + borderWidth) && (nY > m_windowMargin.top())
|
||||
&& (nY < m_windowMargin.top() + borderWidth)) {
|
||||
*result = HTTOPLEFT;
|
||||
} else if (
|
||||
(nX > window->width() - m_windowMargin.right() - borderWidth) && (nX < window->width() - m_windowMargin.right()) && (nY > m_windowMargin.top())
|
||||
&& (nY < m_windowMargin.top() + borderWidth)) {
|
||||
*result = HTTOPRIGHT;
|
||||
} else if (
|
||||
(nX > m_windowMargin.left()) && (nX < m_windowMargin.left() + borderWidth) && (nY > window->height() - m_windowMargin.bottom() - borderWidth)
|
||||
&& (nY < window->height() - m_windowMargin.bottom())) {
|
||||
*result = HTBOTTOMLEFT;
|
||||
} else if (
|
||||
(nX > window->width() - m_windowMargin.right() - borderWidth) && (nX < window->width() - m_windowMargin.right())
|
||||
&& (nY > window->height() - m_windowMargin.bottom() - borderWidth) && (nY < window->height() - m_windowMargin.bottom())) {
|
||||
*result = HTBOTTOMRIGHT;
|
||||
} else if ((nX > m_windowMargin.left()) && (nX < m_windowMargin.left() + borderWidth)) {
|
||||
*result = HTLEFT;
|
||||
} else if ((nX > window->width() - m_windowMargin.right() - borderWidth) && (nX < window->width() - m_windowMargin.right())) {
|
||||
*result = HTRIGHT;
|
||||
} else if ((nY > m_windowMargin.top()) && (nY < m_windowMargin.top() + borderWidth)) {
|
||||
*result = HTTOP;
|
||||
} else if ((nY > window->height() - m_windowMargin.bottom() - borderWidth) && (nY < window->height() - m_windowMargin.bottom())) {
|
||||
*result = HTBOTTOM;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WindowNativeEventFilter::processNcLButtonDown(void *message, long *result)
|
||||
{
|
||||
Q_UNUSED(result);
|
||||
|
||||
MSG *param = static_cast<MSG *>(message);
|
||||
if (!param) {
|
||||
return false;
|
||||
}
|
||||
|
||||
QWindow *window = getWindow((WId)param->hwnd);
|
||||
if (!window) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!(window->flags() & Qt::WindowMaximizeButtonHint) && !(window->flags() & Qt::WindowFullscreenButtonHint)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((window->windowStates() & Qt::WindowMaximized) || (window->windowStates() & Qt::WindowFullScreen)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
HWND hwnd = param->hwnd;
|
||||
WPARAM nHitTest = param->wParam;
|
||||
if (nHitTest == HTTOP) {
|
||||
::PostMessage(hwnd, WM_SYSCOMMAND, SC_SIZE | WMSZ_TOP, param->lParam);
|
||||
} else if (nHitTest == HTBOTTOM) {
|
||||
::PostMessage(hwnd, WM_SYSCOMMAND, SC_SIZE | WMSZ_BOTTOM, param->lParam);
|
||||
} else if (nHitTest == HTLEFT) {
|
||||
::PostMessage(hwnd, WM_SYSCOMMAND, SC_SIZE | WMSZ_LEFT, param->lParam);
|
||||
} else if (nHitTest == HTRIGHT) {
|
||||
::PostMessage(hwnd, WM_SYSCOMMAND, SC_SIZE | WMSZ_RIGHT, param->lParam);
|
||||
} else if (nHitTest == HTTOPLEFT) {
|
||||
::PostMessage(hwnd, WM_SYSCOMMAND, SC_SIZE | WMSZ_TOPLEFT, param->lParam);
|
||||
} else if (nHitTest == HTTOPRIGHT) {
|
||||
::PostMessage(hwnd, WM_SYSCOMMAND, SC_SIZE | WMSZ_TOPRIGHT, param->lParam);
|
||||
} else if (nHitTest == HTBOTTOMLEFT) {
|
||||
::PostMessage(hwnd, WM_SYSCOMMAND, SC_SIZE | WMSZ_BOTTOMLEFT, param->lParam);
|
||||
} else if (nHitTest == HTBOTTOMRIGHT) {
|
||||
::PostMessage(hwnd, WM_SYSCOMMAND, SC_SIZE | WMSZ_BOTTOMRIGHT, param->lParam);
|
||||
} else if (nHitTest == HTCAPTION) {
|
||||
::PostMessage(hwnd, WM_SYSCOMMAND, SC_MOVE + 1, 0);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool WindowNativeEventFilter::processSetCursor(void *message, long *result)
|
||||
{
|
||||
Q_UNUSED(result);
|
||||
|
||||
MSG *param = static_cast<MSG *>(message);
|
||||
if (!param) {
|
||||
return false;
|
||||
}
|
||||
|
||||
QWindow *window = getWindow((WId)param->hwnd);
|
||||
if (!window) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!(window->flags() & Qt::WindowMaximizeButtonHint) && !(window->flags() & Qt::WindowFullscreenButtonHint)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((window->windowStates() & Qt::WindowMaximized) || (window->windowStates() & Qt::WindowFullScreen)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// is invisible window
|
||||
HWND hwnd = param->hwnd;
|
||||
if (!::IsWindowVisible(hwnd)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// is not enabled window
|
||||
if (!::IsWindowEnabled(hwnd)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// set cursor
|
||||
HCURSOR hCursor = nullptr;
|
||||
LPARAM hittest = LOWORD(param->lParam);
|
||||
switch (hittest) {
|
||||
case HTRIGHT:
|
||||
case HTLEFT:
|
||||
hCursor = LoadCursor(nullptr, IDC_SIZEWE);
|
||||
break;
|
||||
case HTTOP:
|
||||
case HTBOTTOM:
|
||||
hCursor = LoadCursor(nullptr, IDC_SIZENS);
|
||||
break;
|
||||
case HTTOPLEFT:
|
||||
case HTBOTTOMRIGHT:
|
||||
hCursor = LoadCursor(nullptr, IDC_SIZENWSE);
|
||||
break;
|
||||
case HTTOPRIGHT:
|
||||
case HTBOTTOMLEFT:
|
||||
hCursor = LoadCursor(nullptr, IDC_SIZENESW);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (!hCursor) {
|
||||
return false;
|
||||
}
|
||||
|
||||
::SetCursor(hCursor);
|
||||
::DestroyCursor(hCursor);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
QWindow *WindowNativeEventFilter::getWindow(WId wndId)
|
||||
{
|
||||
QWindowList windows = QGuiApplication::topLevelWindows();
|
||||
for (int i = 0; i < windows.size(); ++i) {
|
||||
if (windows.at(i)->winId() == wndId) {
|
||||
return windows.at(i);
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
#endif //(Q_OS_WIN)
|
32
QtScrcpy/uibase/windownativeeventfilterwin.h
Normal file
32
QtScrcpy/uibase/windownativeeventfilterwin.h
Normal file
|
@ -0,0 +1,32 @@
|
|||
#pragma once
|
||||
#include <QWindow>
|
||||
|
||||
#if defined(Q_OS_WIN)
|
||||
#include <QAbstractNativeEventFilter>
|
||||
#include <QMargins>
|
||||
|
||||
class WindowNativeEventFilter : public QAbstractNativeEventFilter
|
||||
{
|
||||
protected:
|
||||
WindowNativeEventFilter();
|
||||
~WindowNativeEventFilter() override;
|
||||
|
||||
public:
|
||||
static WindowNativeEventFilter *Instance();
|
||||
|
||||
void Init();
|
||||
bool nativeEventFilter(const QByteArray &eventType, void *message, long *result) override;
|
||||
|
||||
private:
|
||||
bool processNcHitTest(void *message, long *result);
|
||||
bool processNcLButtonDown(void *message, long *result);
|
||||
bool processSetCursor(void *message, long *result);
|
||||
|
||||
QWindow *getWindow(WId wndId);
|
||||
|
||||
private:
|
||||
bool m_inited = false;
|
||||
QMargins m_windowMargin = QMargins(0, 0, 0, 0);
|
||||
};
|
||||
|
||||
#endif // Q_OS_WIN
|
Loading…
Add table
Reference in a new issue