mirror of
https://github.com/barry-ran/QtScrcpy.git
synced 2025-08-03 06:08:39 +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 "dialog.h"
|
||||||
#include "mousetap/mousetap.h"
|
#include "mousetap/mousetap.h"
|
||||||
#include "stream.h"
|
#include "stream.h"
|
||||||
#include "windowframelesshelper.h"
|
#include "windowframelesshelper/windowframelesshelper.h"
|
||||||
|
|
||||||
static Dialog *g_mainDlg = Q_NULLPTR;
|
static Dialog *g_mainDlg = Q_NULLPTR;
|
||||||
|
|
||||||
|
|
|
@ -2,24 +2,22 @@ FORMS +=
|
||||||
|
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
$$PWD/keepratiowidget.h \
|
$$PWD/keepratiowidget.h \
|
||||||
$$PWD/magneticwidget.h \
|
$$PWD/magneticwidget.h
|
||||||
$$PWD/windowframelesshelper.h \
|
|
||||||
$$PWD/windownativeeventfilter.h
|
|
||||||
|
|
||||||
|
|
||||||
SOURCES += \
|
SOURCES += \
|
||||||
$$PWD/keepratiowidget.cpp \
|
$$PWD/keepratiowidget.cpp \
|
||||||
$$PWD/magneticwidget.cpp \
|
$$PWD/magneticwidget.cpp
|
||||||
$$PWD/windownativeeventfilter.cpp
|
|
||||||
|
|
||||||
win32 {
|
win32 {
|
||||||
SOURCES += $$PWD/windowframelesshelper.cpp
|
SOURCES +=
|
||||||
}
|
}
|
||||||
|
|
||||||
mac {
|
mac {
|
||||||
SOURCES += $$PWD/windowframelesshelper.mm
|
SOURCES +=
|
||||||
}
|
}
|
||||||
|
|
||||||
linux {
|
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 "windowframelesshelper.h"
|
||||||
#include "windownativeeventfilter.h"
|
#include "windowframelessmanager.h"
|
||||||
|
|
||||||
WindowFramelessHelper::WindowFramelessHelper(QObject *parent) : QObject(parent)
|
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
|
QQuickWindow *WindowFramelessHelper::target() const
|
||||||
|
@ -13,18 +21,10 @@ QQuickWindow *WindowFramelessHelper::target() const
|
||||||
|
|
||||||
void WindowFramelessHelper::setTarget(QQuickWindow *target)
|
void WindowFramelessHelper::setTarget(QQuickWindow *target)
|
||||||
{
|
{
|
||||||
if (target == m_target) {
|
if (target == nullptr || target == m_target) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
m_target = target;
|
m_target = target;
|
||||||
|
|
||||||
#ifdef Q_OS_WIN32
|
|
||||||
WindowNativeEventFilter::Instance()->Init();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
emit targetChanged();
|
emit targetChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
void WindowFramelessHelper::updateStyle() {
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,5 +1,4 @@
|
||||||
#ifndef WindowFramelessHelper_H
|
#pragma once
|
||||||
#define WindowFramelessHelper_H
|
|
||||||
|
|
||||||
#include <QQuickWindow>
|
#include <QQuickWindow>
|
||||||
|
|
||||||
|
@ -10,18 +9,14 @@ class WindowFramelessHelper : public QObject
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit WindowFramelessHelper(QObject *parent = nullptr);
|
explicit WindowFramelessHelper(QObject *parent = nullptr);
|
||||||
|
virtual ~WindowFramelessHelper();
|
||||||
|
|
||||||
QQuickWindow *target() const;
|
QQuickWindow *target() const;
|
||||||
void setTarget(QQuickWindow *target);
|
void setTarget(QQuickWindow *target);
|
||||||
|
|
||||||
protected:
|
|
||||||
void updateStyle();
|
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void targetChanged();
|
void targetChanged();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QQuickWindow* m_target = nullptr;
|
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 <Cocoa/Cocoa.h>
|
||||||
#include <QOperatingSystemVersion>
|
#include <QOperatingSystemVersion>
|
||||||
#import <objc/runtime.h>
|
#import <objc/runtime.h>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
#include "windowframelessmanager.h"
|
||||||
|
|
||||||
|
windownativeeventfiltermac::windownativeeventfiltermac()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void SwizzleSelector(Class originalCls, SEL originalSelector, Class swizzledCls, SEL swizzledSelector) {
|
void SwizzleSelector(Class originalCls, SEL originalSelector, Class swizzledCls, SEL swizzledSelector) {
|
||||||
Method originalMethod = class_getInstanceMethod(originalCls, originalSelector);
|
Method originalMethod = class_getInstanceMethod(originalCls, originalSelector);
|
||||||
|
@ -48,16 +54,20 @@ void SwizzleSelector(Class originalCls, SEL originalSelector, Class swizzledCls,
|
||||||
{
|
{
|
||||||
[self filter_setStyleMask:styleMask];
|
[self filter_setStyleMask:styleMask];
|
||||||
|
|
||||||
//设置标题文字和图标为不可见
|
WindowFramelessHelper* win = WindowFramelessManager::Instance()->getWindowByHandle((quint64)self);
|
||||||
self.titleVisibility = NSWindowTitleHidden;
|
|
||||||
//设置标题栏为透明
|
if (win) {
|
||||||
self.titlebarAppearsTransparent = YES;
|
//设置标题文字和图标为不可见
|
||||||
//设置不可由标题栏拖动,避免与自定义拖动冲突
|
self.titleVisibility = NSWindowTitleHidden;
|
||||||
self.movable = NO;
|
//设置标题栏为透明
|
||||||
self.hasShadow = YES;
|
self.titlebarAppearsTransparent = YES;
|
||||||
//设置view扩展到标题栏
|
//设置不可由标题栏拖动,避免与自定义拖动冲突
|
||||||
if (!(self.styleMask & NSWindowStyleMaskFullSizeContentView)) {
|
self.movable = NO;
|
||||||
self.styleMask |= NSWindowStyleMaskFullSizeContentView;
|
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];
|
[self filter_setTitlebarAppearsTransparent:titlebarAppearsTransparent];
|
||||||
}
|
}
|
||||||
@end
|
@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
Add a link
Reference in a new issue