redesign API

This commit is contained in:
Yuhang Zhao 2021-05-31 10:33:54 +08:00
parent 6f98dd8930
commit 4139cf0ab2
17 changed files with 266 additions and 258 deletions

View File

@ -1,8 +1,9 @@
cmake_minimum_required(VERSION 3.18) cmake_minimum_required(VERSION 3.15)
project(FramelessHelper LANGUAGES CXX) project(FramelessHelper LANGUAGES CXX)
option(BUILD_EXAMPLES "Build examples." ON) option(BUILD_EXAMPLES "Build examples." ON)
option(TEST_UNIX "Test UNIX version (from Win32)." OFF)
set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_STANDARD_REQUIRED ON)
@ -14,7 +15,7 @@ set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTOMOC ON) set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON) set(CMAKE_AUTORCC ON)
if(NOT CMAKE_DEBUG_POSTFIX) if(NOT DEFINED CMAKE_DEBUG_POSTFIX)
if(WIN32) if(WIN32)
set(CMAKE_DEBUG_POSTFIX d) set(CMAKE_DEBUG_POSTFIX d)
else() else()
@ -22,15 +23,23 @@ if(NOT CMAKE_DEBUG_POSTFIX)
endif() endif()
endif() endif()
if(NOT CMAKE_RUNTIME_OUTPUT_DIRECTORY) if(NOT DEFINED CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Release)
endif()
if(NOT (CMAKE_BUILD_TYPE STREQUAL "Debug"))
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION ON)
endif()
if(NOT DEFINED CMAKE_RUNTIME_OUTPUT_DIRECTORY)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin)
endif() endif()
if(NOT CMAKE_LIBRARY_OUTPUT_DIRECTORY) if(NOT DEFINED CMAKE_LIBRARY_OUTPUT_DIRECTORY)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib) set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib)
endif() endif()
if(NOT CMAKE_ARCHIVE_OUTPUT_DIRECTORY) if(NOT DEFINED CMAKE_ARCHIVE_OUTPUT_DIRECTORY)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib) set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib)
endif() endif()
@ -41,6 +50,8 @@ find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Quick)
set(SOURCES set(SOURCES
framelesshelper_global.h framelesshelper_global.h
framelesshelper.h
framelesshelper.cpp
framelesswindowsmanager.h framelesswindowsmanager.h
framelesswindowsmanager.cpp framelesswindowsmanager.cpp
utilities.h utilities.h
@ -61,10 +72,6 @@ if(WIN32)
framelesshelper_win32.cpp framelesshelper_win32.cpp
) )
else() else()
list(APPEND SOURCES
framelesshelper.h
framelesshelper.cpp
)
if(MACOS) if(MACOS)
list(APPEND SOURCES utilities_macos.mm) list(APPEND SOURCES utilities_macos.mm)
else() else()
@ -99,10 +106,14 @@ target_compile_definitions(${PROJECT_NAME} PRIVATE
QT_NO_CAST_TO_ASCII QT_NO_CAST_TO_ASCII
QT_NO_KEYWORDS QT_NO_KEYWORDS
QT_DEPRECATED_WARNINGS QT_DEPRECATED_WARNINGS
QT_DISABLE_DEPRECATED_BEFORE=0x060000 QT_DISABLE_DEPRECATED_BEFORE=0x060100
FRAMELESSHELPER_BUILD_LIBRARY FRAMELESSHELPER_BUILD_LIBRARY
) )
if(TEST_UNIX)
target_compile_definitions(${PROJECT_NAME} PRIVATE FRAMELESSHELPER_TEST_UNIX)
endif()
if(WIN32) if(WIN32)
target_compile_definitions(${PROJECT_NAME} PRIVATE target_compile_definitions(${PROJECT_NAME} PRIVATE
WIN32_LEAN_AND_MEAN WIN32_LEAN_AND_MEAN

View File

@ -79,11 +79,11 @@ void MainWindow::showEvent(QShowEvent *event)
const auto win = windowHandle(); const auto win = windowHandle();
if (win) { if (win) {
FramelessWindowsManager::addWindow(win); FramelessWindowsManager::addWindow(win);
FramelessWindowsManager::addIgnoreObject(win, titleBarWidget->iconButton); FramelessWindowsManager::setHitTestVisible(win, titleBarWidget->iconButton, true);
FramelessWindowsManager::addIgnoreObject(win, titleBarWidget->minimizeButton); FramelessWindowsManager::setHitTestVisible(win, titleBarWidget->minimizeButton, true);
FramelessWindowsManager::addIgnoreObject(win, titleBarWidget->maximizeButton); FramelessWindowsManager::setHitTestVisible(win, titleBarWidget->maximizeButton, true);
FramelessWindowsManager::addIgnoreObject(win, titleBarWidget->closeButton); FramelessWindowsManager::setHitTestVisible(win, titleBarWidget->closeButton, true);
FramelessWindowsManager::addIgnoreObject(win, appMainWindow->menubar); FramelessWindowsManager::setHitTestVisible(win, appMainWindow->menubar, true);
inited = true; inited = true;
} }
} }

View File

@ -79,7 +79,7 @@ Window {
MinimizeButton { MinimizeButton {
id: minimizeButton id: minimizeButton
onClicked: window.showMinimized() onClicked: window.showMinimized()
Component.onCompleted: framelessHelper.addIgnoreObject(minimizeButton) Component.onCompleted: framelessHelper.setHitTestVisible(minimizeButton, true)
} }
MaximizeButton { MaximizeButton {
@ -92,13 +92,13 @@ Window {
window.showMaximized() window.showMaximized()
} }
} }
Component.onCompleted: framelessHelper.addIgnoreObject(maximizeButton) Component.onCompleted: framelessHelper.setHitTestVisible(maximizeButton, true)
} }
CloseButton { CloseButton {
id: closeButton id: closeButton
onClicked: window.close() onClicked: window.close()
Component.onCompleted: framelessHelper.addIgnoreObject(closeButton) Component.onCompleted: framelessHelper.setHitTestVisible(closeButton, true)
} }
} }
} }

View File

@ -46,7 +46,11 @@ void Widget::showEvent(QShowEvent *event)
QWidget::showEvent(event); QWidget::showEvent(event);
static bool inited = false; static bool inited = false;
if (!inited) { if (!inited) {
FramelessWindowsManager::addWindow(windowHandle()); QWindow *win = windowHandle();
FramelessWindowsManager::addWindow(win);
FramelessWindowsManager::setHitTestVisible(win, m_minimizeButton, true);
FramelessWindowsManager::setHitTestVisible(win, m_maximizeButton, true);
FramelessWindowsManager::setHitTestVisible(win, m_closeButton, true);
inited = true; inited = true;
} }
} }
@ -134,9 +138,6 @@ void Widget::setupUi()
m_closeButton->setIcon(QIcon{QStringLiteral(":/images/button_close_black.svg")}); m_closeButton->setIcon(QIcon{QStringLiteral(":/images/button_close_black.svg")});
m_closeButton->setIconSize(systemButtonSize); m_closeButton->setIconSize(systemButtonSize);
connect(m_closeButton, &QPushButton::clicked, this, &Widget::close); connect(m_closeButton, &QPushButton::clicked, this, &Widget::close);
FramelessWindowsManager::addIgnoreObject(win, m_minimizeButton);
FramelessWindowsManager::addIgnoreObject(win, m_maximizeButton);
FramelessWindowsManager::addIgnoreObject(win, m_closeButton);
const auto systemButtonLayout = new QHBoxLayout; const auto systemButtonLayout = new QHBoxLayout;
systemButtonLayout->setContentsMargins(0, 0, 0, 0); systemButtonLayout->setContentsMargins(0, 0, 0, 0);
systemButtonLayout->setSpacing(0); systemButtonLayout->setSpacing(0);

View File

@ -63,44 +63,30 @@ void FramelessHelper::setTitleBarHeight(const int val)
m_titleBarHeight = val; m_titleBarHeight = val;
} }
QObjectList FramelessHelper::getIgnoreObjects(const QWindow *window) const
{
Q_ASSERT(window);
QObjectList ret{};
const QObjectList objs = m_ignoreObjects.value(window);
if (!objs.isEmpty()) {
for (auto &&_obj : qAsConst(objs)) {
if (_obj) {
ret.append(_obj);
}
}
}
return ret;
}
void FramelessHelper::addIgnoreObject(const QWindow *window, QObject *val)
{
Q_ASSERT(window);
QObjectList objs = m_ignoreObjects[window];
objs.append(val);
m_ignoreObjects[window] = objs;
}
bool FramelessHelper::getResizable(const QWindow *window) const bool FramelessHelper::getResizable(const QWindow *window) const
{ {
Q_ASSERT(window); Q_ASSERT(window);
if (!window) {
return false;
}
return !m_fixedSize.value(window); return !m_fixedSize.value(window);
} }
void FramelessHelper::setResizable(const QWindow *window, const bool val) void FramelessHelper::setResizable(const QWindow *window, const bool val)
{ {
Q_ASSERT(window); Q_ASSERT(window);
m_fixedSize[window] = !val; if (!window) {
return;
}
m_fixedSize.insert(window, !val);
} }
void FramelessHelper::removeWindowFrame(QWindow *window) void FramelessHelper::removeWindowFrame(QWindow *window)
{ {
Q_ASSERT(window); Q_ASSERT(window);
if (!window) {
return;
}
// TODO: check whether these flags are correct for Linux and macOS. // TODO: check whether these flags are correct for Linux and macOS.
window->setFlags(Qt::Window | Qt::FramelessWindowHint | Qt::WindowSystemMenuHint window->setFlags(Qt::Window | Qt::FramelessWindowHint | Qt::WindowSystemMenuHint
| Qt::WindowMinMaxButtonsHint | Qt::WindowTitleHint); | Qt::WindowMinMaxButtonsHint | Qt::WindowTitleHint);
@ -112,6 +98,9 @@ bool FramelessHelper::eventFilter(QObject *object, QEvent *event)
{ {
Q_ASSERT(object); Q_ASSERT(object);
Q_ASSERT(event); Q_ASSERT(event);
if (!object || !event) {
return false;
}
if (!object->isWindowType()) { if (!object->isWindowType()) {
return false; return false;
} }
@ -165,22 +154,22 @@ bool FramelessHelper::eventFilter(QObject *object, QEvent *event)
} }
return Qt::CursorShape::ArrowCursor; return Qt::CursorShape::ArrowCursor;
}; };
const auto isInTitlebarArea = [this](const QPointF &globalPoint, const auto isInTitlebarArea = [this](const QPointF &point, const QWindow *window) -> bool {
const QPointF &point,
const QWindow *window) -> bool {
Q_ASSERT(window); Q_ASSERT(window);
return (point.y() <= m_titleBarHeight) if (!window) {
&& !Utilities::isMouseInSpecificObjects(globalPoint, getIgnoreObjects(window)); return false;
}
return (point.y() <= m_titleBarHeight) && !Utilities::isHitTestVisible(window);
}; };
const auto moveOrResize = const auto moveOrResize =
[this, &getWindowEdges, &isInTitlebarArea](const QPointF &globalPoint, [this, &getWindowEdges, &isInTitlebarArea](const QPointF &point, QWindow *window) {
const QPointF &point,
QWindow *window) {
Q_ASSERT(window); Q_ASSERT(window);
//const QPointF deltaPoint = globalPoint - m_pOldMousePos; if (!window) {
return;
}
const Qt::Edges edges = getWindowEdges(point, window->width(), window->height()); const Qt::Edges edges = getWindowEdges(point, window->width(), window->height());
if (edges == Qt::Edges{}) { if (edges == Qt::Edges{}) {
if (isInTitlebarArea(globalPoint, point, window)) { if (isInTitlebarArea(point, window)) {
if (!window->startSystemMove()) { if (!window->startSystemMove()) {
// ### FIXME: TO BE IMPLEMENTED! // ### FIXME: TO BE IMPLEMENTED!
qWarning() << "Current OS doesn't support QWindow::startSystemMove()."; qWarning() << "Current OS doesn't support QWindow::startSystemMove().";
@ -188,8 +177,7 @@ bool FramelessHelper::eventFilter(QObject *object, QEvent *event)
} }
} else { } else {
if ((window->windowState() == Qt::WindowState::WindowNoState) if ((window->windowState() == Qt::WindowState::WindowNoState)
&& !Utilities::isMouseInSpecificObjects(globalPoint, getIgnoreObjects(window)) && !Utilities::isHitTestVisible(window) && getResizable(window)) {
&& getResizable(window)) {
if (!window->startSystemResize(edges)) { if (!window->startSystemResize(edges)) {
// ### FIXME: TO BE IMPLEMENTED! // ### FIXME: TO BE IMPLEMENTED!
qWarning() << "Current OS doesn't support QWindow::startSystemResize()."; qWarning() << "Current OS doesn't support QWindow::startSystemResize().";
@ -199,6 +187,9 @@ bool FramelessHelper::eventFilter(QObject *object, QEvent *event)
}; };
const auto getMousePos = [](const QMouseEvent *e, const bool global) -> QPointF { const auto getMousePos = [](const QMouseEvent *e, const bool global) -> QPointF {
Q_ASSERT(e); Q_ASSERT(e);
if (!e) {
return {};
}
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
return global ? e->globalPosition() : e->scenePosition(); return global ? e->globalPosition() : e->scenePosition();
#else #else
@ -212,9 +203,7 @@ bool FramelessHelper::eventFilter(QObject *object, QEvent *event)
if (mouseEvent->button() != Qt::MouseButton::LeftButton) { if (mouseEvent->button() != Qt::MouseButton::LeftButton) {
break; break;
} }
if (isInTitlebarArea(getMousePos(mouseEvent, true), if (isInTitlebarArea(getMousePos(mouseEvent, false), currentWindow)) {
getMousePos(mouseEvent, false),
currentWindow)) {
if (currentWindow->windowState() == Qt::WindowState::WindowFullScreen) { if (currentWindow->windowState() == Qt::WindowState::WindowFullScreen) {
break; break;
} }
@ -235,9 +224,7 @@ bool FramelessHelper::eventFilter(QObject *object, QEvent *event)
} }
m_bIsMRBPressed = true; m_bIsMRBPressed = true;
m_pOldMousePos = getMousePos(mouseEvent, true); m_pOldMousePos = getMousePos(mouseEvent, true);
moveOrResize(getMousePos(mouseEvent, true), moveOrResize(getMousePos(mouseEvent, false), currentWindow);
getMousePos(mouseEvent, false),
currentWindow);
} }
} break; } break;
case QEvent::MouseMove: { case QEvent::MouseMove: {
@ -265,12 +252,11 @@ bool FramelessHelper::eventFilter(QObject *object, QEvent *event)
case QEvent::TouchBegin: case QEvent::TouchBegin:
case QEvent::TouchUpdate: { case QEvent::TouchUpdate: {
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
const auto point = static_cast<QTouchEvent *>(event)->points().first(); const auto point = static_cast<QTouchEvent *>(event)->points().first().position();
moveOrResize(point.globalPosition(), point.position(), currentWindow);
#else #else
const auto point = static_cast<QTouchEvent *>(event)->touchPoints().first(); const auto point = static_cast<QTouchEvent *>(event)->touchPoints().first().pos();
moveOrResize(point.screenPos(), point.pos(), currentWindow);
#endif #endif
moveOrResize(point, currentWindow);
} break; } break;
default: default:
break; break;

View File

@ -1,7 +1,7 @@
/* /*
* MIT License * MIT License
* *
* Copyright (C) 2020 by wangwenx190 (Yuhang Zhao) * Copyright (C) 2021 by wangwenx190 (Yuhang Zhao)
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@ -34,7 +34,7 @@ QT_BEGIN_NAMESPACE
QT_FORWARD_DECLARE_CLASS(QWindow) QT_FORWARD_DECLARE_CLASS(QWindow)
QT_END_NAMESPACE QT_END_NAMESPACE
class FRAMELESSHELPER_EXPORT FramelessHelper : public QObject class FRAMELESSHELPER_API FramelessHelper : public QObject
{ {
Q_OBJECT Q_OBJECT
Q_DISABLE_COPY_MOVE(FramelessHelper) Q_DISABLE_COPY_MOVE(FramelessHelper)
@ -54,9 +54,6 @@ public:
int getTitleBarHeight() const; int getTitleBarHeight() const;
void setTitleBarHeight(const int val); void setTitleBarHeight(const int val);
void addIgnoreObject(const QWindow *window, QObject *val);
QObjectList getIgnoreObjects(const QWindow *window) const;
bool getResizable(const QWindow *window) const; bool getResizable(const QWindow *window) const;
void setResizable(const QWindow *window, const bool val); void setResizable(const QWindow *window, const bool val);
@ -68,7 +65,6 @@ private:
// the scale factor is 1.0. Don't know how to acquire these values on UNIX // the scale factor is 1.0. Don't know how to acquire these values on UNIX
// platforms through native API. // platforms through native API.
int m_borderWidth = 8, m_borderHeight = 8, m_titleBarHeight = 30; int m_borderWidth = 8, m_borderHeight = 8, m_titleBarHeight = 30;
QHash<const QWindow *, QObjectList> m_ignoreObjects = {};
QHash<const QWindow *, bool> m_fixedSize = {}; QHash<const QWindow *, bool> m_fixedSize = {};
}; };
#endif #endif

View File

@ -1,7 +1,7 @@
/* /*
* MIT License * MIT License
* *
* Copyright (C) 2020 by wangwenx190 (Yuhang Zhao) * Copyright (C) 2021 by wangwenx190 (Yuhang Zhao)
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal

View File

@ -26,14 +26,14 @@
#include <QtCore/qglobal.h> #include <QtCore/qglobal.h>
#ifndef FRAMELESSHELPER_EXPORT #ifndef FRAMELESSHELPER_API
#ifdef FRAMELESSHELPER_STATIC #ifdef FRAMELESSHELPER_STATIC
#define FRAMELESSHELPER_EXPORT #define FRAMELESSHELPER_API
#else #else
#ifdef FRAMELESSHELPER_BUILD_LIBRARY #ifdef FRAMELESSHELPER_BUILD_LIBRARY
#define FRAMELESSHELPER_EXPORT Q_DECL_EXPORT #define FRAMELESSHELPER_API Q_DECL_EXPORT
#else #else
#define FRAMELESSHELPER_EXPORT Q_DECL_IMPORT #define FRAMELESSHELPER_API Q_DECL_IMPORT
#endif #endif
#endif #endif
#endif #endif
@ -42,31 +42,31 @@
#define Q_OS_WINDOWS #define Q_OS_WINDOWS
#endif #endif
#ifndef Q_DISABLE_MOVE #ifndef Q_DISABLE_COPY_MOVE
#define Q_DISABLE_MOVE(Class) \ #define Q_DISABLE_COPY_MOVE(Class) \
Q_DISABLE_COPY(Class) \
Class(Class &&) = delete; \ Class(Class &&) = delete; \
Class &operator=(Class &&) = delete; Class &operator=(Class &&) = delete;
#endif #endif
#ifndef Q_DISABLE_COPY_MOVE
#define Q_DISABLE_COPY_MOVE(Class) \
Q_DISABLE_COPY(Class) \
Q_DISABLE_MOVE(Class)
#endif
#if (QT_VERSION < QT_VERSION_CHECK(5, 7, 0)) #if (QT_VERSION < QT_VERSION_CHECK(5, 7, 0))
#define qAsConst(i) std::as_const(i) #define qAsConst(i) std::as_const(i)
#endif #endif
#if !defined(Q_OS_WINDOWS) || defined(FRAMELESSHELPER_TEST_UNIX)
#define FRAMELESSHELPER_USE_UNIX_VERSION
#endif
namespace _flh_global { namespace _flh_global {
[[maybe_unused]] const char _flh_framelessEnabled_flag[] = "_FRAMELESSHELPER_FRAMELESS_MODE_ENABLED"; [[maybe_unused]] const char _flh_framelessEnabled_flag[] = "_FRAMELESSHELPER_FRAMELESS_MODE_ENABLED";
[[maybe_unused]] const char _flh_borderWidth_flag[] = "_FRAMELESSHELPER_WINDOW_BORDER_WIDTH"; [[maybe_unused]] const char _flh_borderWidth_flag[] = "_FRAMELESSHELPER_WINDOW_BORDER_WIDTH";
[[maybe_unused]] const char _flh_borderHeight_flag[] = "_FRAMELESSHELPER_WINDOW_BORDER_HEIGHT"; [[maybe_unused]] const char _flh_borderHeight_flag[] = "_FRAMELESSHELPER_WINDOW_BORDER_HEIGHT";
[[maybe_unused]] const char _flh_titleBarHeight_flag[] = "_FRAMELESSHELPER_WINDOW_TITLE_BAR_HEIGHT"; [[maybe_unused]] const char _flh_titleBarHeight_flag[] = "_FRAMELESSHELPER_WINDOW_TITLE_BAR_HEIGHT";
[[maybe_unused]] const char _flh_ignoredObjects_flag[] = "_FRAMELESSHELPER_WINDOW_TITLE_BAR_IGNORED_OBJECTS"; [[maybe_unused]] const char _flh_hitTestVisible_flag[] = "_FRAMELESSHELPER_HIT_TEST_VISIBLE";
[[maybe_unused]] const char _flh_useNativeTitleBar_flag[] = "_FRAMELESSHELPER_USE_NATIVE_TITLE_BAR"; [[maybe_unused]] const char _flh_useNativeTitleBar_flag[] = "_FRAMELESSHELPER_USE_NATIVE_TITLE_BAR";
[[maybe_unused]] const char _flh_preserveNativeFrame_flag[] = "_FRAMELESSHELPER_PRESERVE_NATIVE_WINDOW_FRAME"; [[maybe_unused]] const char _flh_preserveNativeFrame_flag[] = "_FRAMELESSHELPER_PRESERVE_NATIVE_WINDOW_FRAME";
[[maybe_unused]] const char _flh_forcePreserveNativeFrame_flag[] = "_FRAMELESSHELPER_FORCE_PRESERVE_NATIVE_WINDOW_FRAME"; [[maybe_unused]] const char _flh_forcePreserveNativeFrame_flag[] = "_FRAMELESSHELPER_FORCE_PRESERVE_NATIVE_WINDOW_FRAME";
[[maybe_unused]] const char _flh_nativeParent_flag[] = "_FRAMELESSHELPER_NATIVE_PARENT";
} }

View File

@ -156,42 +156,13 @@ void FramelessHelperWin::removeFramelessWindow(QWindow *window)
installHelper(window, false); installHelper(window, false);
} }
void FramelessHelperWin::setIgnoredObjects(QWindow *window, const QObjectList &objects)
{
Q_ASSERT(window);
if (!window) {
return;
}
window->setProperty(_flh_global::_flh_ignoredObjects_flag, QVariant::fromValue(objects));
}
QObjectList FramelessHelperWin::getIgnoredObjects(const QWindow *window)
{
Q_ASSERT(window);
if (!window) {
return {};
}
return qvariant_cast<QObjectList>(window->property(_flh_global::_flh_ignoredObjects_flag));
}
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
bool FramelessHelperWin::nativeEventFilter(const QByteArray &eventType, void *message, qintptr *result) bool FramelessHelperWin::nativeEventFilter(const QByteArray &eventType, void *message, qintptr *result)
#else #else
bool FramelessHelperWin::nativeEventFilter(const QByteArray &eventType, void *message, long *result) bool FramelessHelperWin::nativeEventFilter(const QByteArray &eventType, void *message, long *result)
#endif #endif
{ {
// "result" can't be null in theory and I don't see any projects check if ((eventType != QByteArrayLiteral("windows_generic_MSG")) || !message || !result) {
// this, everyone is assuming it will never be null, including Microsoft,
// but according to Lucas, frameless applications crashed on many Win7
// machines because it's null. The temporary solution is also strange:
// upgrade drivers or switch to the basic theme.
if (!result) {
return false;
}
// The example code in Qt's documentation has this check. I don't know
// whether we really need this check or not, but adding this check won't
// bring us harm anyway.
if (eventType != "windows_generic_MSG") {
return false; return false;
} }
#if (QT_VERSION == QT_VERSION_CHECK(5, 11, 1)) #if (QT_VERSION == QT_VERSION_CHECK(5, 11, 1))
@ -200,13 +171,13 @@ bool FramelessHelperWin::nativeEventFilter(const QByteArray &eventType, void *me
#else #else
const auto msg = static_cast<LPMSG>(message); const auto msg = static_cast<LPMSG>(message);
#endif #endif
if (!msg || (msg && !msg->hwnd)) { if (!msg->hwnd) {
// Why sometimes the window handle is null? Is it designed to be? // Why sometimes the window handle is null? Is it designed to be?
// Anyway, we should skip it in this case. // Anyway, we should skip it in this case.
return false; return false;
} }
const QWindow *window = Utilities::findWindow(reinterpret_cast<WId>(msg->hwnd)); const QWindow *window = Utilities::findWindow(reinterpret_cast<WId>(msg->hwnd));
if (!window || (window && !window->property(_flh_global::_flh_framelessEnabled_flag).toBool())) { if (!window || !window->property(_flh_global::_flh_framelessEnabled_flag).toBool()) {
return false; return false;
} }
switch (msg->message) { switch (msg->message) {
@ -551,15 +522,13 @@ bool FramelessHelperWin::nativeEventFilter(const QByteArray &eventType, void *me
break; break;
} }
const qreal dpr = window->devicePixelRatio(); const QPointF globalMouse = Utilities::getGlobalMousePosition(window);
const QPointF globalMouse = QCursor::pos(window->screen()) * dpr;
POINT winLocalMouse = {qRound(globalMouse.x()), qRound(globalMouse.y())}; POINT winLocalMouse = {qRound(globalMouse.x()), qRound(globalMouse.y())};
ScreenToClient(msg->hwnd, &winLocalMouse); ScreenToClient(msg->hwnd, &winLocalMouse);
const QPointF localMouse = {static_cast<qreal>(winLocalMouse.x), static_cast<qreal>(winLocalMouse.y)}; const QPointF localMouse = {static_cast<qreal>(winLocalMouse.x), static_cast<qreal>(winLocalMouse.y)};
const bool isInIgnoreObjects = Utilities::isMouseInSpecificObjects(globalMouse, getIgnoredObjects(window), dpr);
const int bh = getSystemMetric(window, Utilities::SystemMetric::BorderHeight, true); const int bh = getSystemMetric(window, Utilities::SystemMetric::BorderHeight, true);
const int tbh = getSystemMetric(window, Utilities::SystemMetric::TitleBarHeight, true); const int tbh = getSystemMetric(window, Utilities::SystemMetric::TitleBarHeight, true);
const bool isTitleBar = (localMouse.y() <= tbh) && !isInIgnoreObjects; const bool isTitleBar = (localMouse.y() <= tbh) && !Utilities::isHitTestVisible(window);
const bool isTop = localMouse.y() <= bh; const bool isTop = localMouse.y() <= bh;
if (shouldHaveWindowFrame()) { if (shouldHaveWindowFrame()) {
// This will handle the left, right and bottom parts of the frame // This will handle the left, right and bottom parts of the frame

View File

@ -32,7 +32,7 @@ QT_BEGIN_NAMESPACE
QT_FORWARD_DECLARE_CLASS(QWindow) QT_FORWARD_DECLARE_CLASS(QWindow)
QT_END_NAMESPACE QT_END_NAMESPACE
class FRAMELESSHELPER_EXPORT FramelessHelperWin : public QAbstractNativeEventFilter class FRAMELESSHELPER_API FramelessHelperWin : public QAbstractNativeEventFilter
{ {
Q_DISABLE_COPY_MOVE(FramelessHelperWin) Q_DISABLE_COPY_MOVE(FramelessHelperWin)
@ -44,9 +44,6 @@ public:
static bool isWindowFrameless(const QWindow *window); static bool isWindowFrameless(const QWindow *window);
static void removeFramelessWindow(QWindow *window); static void removeFramelessWindow(QWindow *window);
static void setIgnoredObjects(QWindow *window, const QObjectList &objects);
static QObjectList getIgnoredObjects(const QWindow *window);
static void setBorderWidth(QWindow *window, const int bw); static void setBorderWidth(QWindow *window, const int bw);
static void setBorderHeight(QWindow *window, const int bh); static void setBorderHeight(QWindow *window, const int bh);
static void setTitleBarHeight(QWindow *window, const int tbh); static void setTitleBarHeight(QWindow *window, const int tbh);

View File

@ -97,11 +97,11 @@ void FramelessQuickHelper::removeWindowFrame()
FramelessWindowsManager::addWindow(window()); FramelessWindowsManager::addWindow(window());
} }
void FramelessQuickHelper::addIgnoreObject(QQuickItem *val) void FramelessQuickHelper::setHitTestVisible(QQuickItem *item, const bool visible)
{ {
Q_ASSERT(val); Q_ASSERT(item);
if (!val) { if (!item) {
return; return;
} }
FramelessWindowsManager::addIgnoreObject(window(), val); FramelessWindowsManager::setHitTestVisible(window(), item, visible);
} }

View File

@ -27,11 +27,11 @@
#include "framelesshelper_global.h" #include "framelesshelper_global.h"
#include <QtQuick/qquickitem.h> #include <QtQuick/qquickitem.h>
class FRAMELESSHELPER_EXPORT FramelessQuickHelper : public QQuickItem class FRAMELESSHELPER_API FramelessQuickHelper : public QQuickItem
{ {
Q_OBJECT Q_OBJECT
Q_DISABLE_COPY_MOVE(FramelessQuickHelper) Q_DISABLE_COPY_MOVE(FramelessQuickHelper)
#if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)) #ifdef QML_NAMED_ELEMENT
QML_NAMED_ELEMENT(FramelessHelper) QML_NAMED_ELEMENT(FramelessHelper)
#endif #endif
Q_PROPERTY(int borderWidth READ borderWidth WRITE setBorderWidth NOTIFY borderWidthChanged) Q_PROPERTY(int borderWidth READ borderWidth WRITE setBorderWidth NOTIFY borderWidthChanged)
@ -60,7 +60,7 @@ public:
public Q_SLOTS: public Q_SLOTS:
void removeWindowFrame(); void removeWindowFrame();
void addIgnoreObject(QQuickItem *val); void setHitTestVisible(QQuickItem *item, const bool visible);
Q_SIGNALS: Q_SIGNALS:
void borderWidthChanged(); void borderWidthChanged();

View File

@ -23,136 +23,141 @@
*/ */
#include "framelesswindowsmanager.h" #include "framelesswindowsmanager.h"
#include <QtCore/qvariant.h>
#include <QtGui/qwindow.h> #include <QtGui/qwindow.h>
#include "utilities.h" #include "utilities.h"
#ifdef Q_OS_WINDOWS #ifdef FRAMELESSHELPER_USE_UNIX_VERSION
#include "framelesshelper.h"
#else
#include <QtGui/qscreen.h> #include <QtGui/qscreen.h>
#include "framelesshelper_win32.h" #include "framelesshelper_win32.h"
#else
#include "framelesshelper.h"
#endif #endif
#ifndef Q_OS_WINDOWS #ifdef FRAMELESSHELPER_USE_UNIX_VERSION
Q_GLOBAL_STATIC(FramelessHelper, framelessHelper) Q_GLOBAL_STATIC(FramelessHelper, framelessHelper)
#endif #endif
FramelessWindowsManager::FramelessWindowsManager() = default; FramelessWindowsManager::FramelessWindowsManager() = default;
void FramelessWindowsManager::addWindow(const QWindow *window) void FramelessWindowsManager::addWindow(QWindow *window)
{ {
Q_ASSERT(window); Q_ASSERT(window);
if (!window) { if (!window) {
return; return;
} }
#ifdef Q_OS_WINDOWS #ifdef FRAMELESSHELPER_USE_UNIX_VERSION
const auto win = const_cast<QWindow *>(window); framelessHelper()->removeWindowFrame(window);
FramelessHelperWin::addFramelessWindow(win);
// Work-around a Win32 multi-monitor bug.
QObject::connect(win, &QWindow::screenChanged, [win](QScreen *screen){
Q_UNUSED(screen);
win->resize(win->size());
});
#else #else
framelessHelper()->removeWindowFrame(const_cast<QWindow *>(window)); FramelessHelperWin::addFramelessWindow(window);
// Work-around a Win32 multi-monitor bug.
QObject::connect(window, &QWindow::screenChanged, [window](QScreen *screen){
Q_UNUSED(screen);
window->resize(window->size());
});
#endif #endif
} }
void FramelessWindowsManager::addIgnoreObject(const QWindow *window, QObject *object) void FramelessWindowsManager::setHitTestVisible(QWindow *window, QObject *object, const bool value)
{ {
Q_ASSERT(window); Q_ASSERT(window);
if (!window) { Q_ASSERT(object);
if (!window || !object) {
return; return;
} }
#ifdef Q_OS_WINDOWS if (!object->isWidgetType() && !object->inherits("QQuickItem")) {
QObjectList objects = FramelessHelperWin::getIgnoredObjects(window); qWarning() << object << "is not a QWidget or QQuickItem.";
objects.append(object); return;
FramelessHelperWin::setIgnoredObjects(const_cast<QWindow *>(window), objects); }
#else const QObject *nativeParent = Utilities::getNativeParent(object);
framelessHelper()->addIgnoreObject(window, object); Q_ASSERT(nativeParent);
#endif if (!nativeParent) {
return;
}
window->setProperty(_flh_global::_flh_nativeParent_flag, QVariant::fromValue(nativeParent));
object->setProperty(_flh_global::_flh_hitTestVisible_flag, value);
} }
int FramelessWindowsManager::getBorderWidth(const QWindow *window) int FramelessWindowsManager::getBorderWidth(const QWindow *window)
{ {
#ifdef Q_OS_WINDOWS #ifdef FRAMELESSHELPER_USE_UNIX_VERSION
Q_UNUSED(window);
return framelessHelper()->getBorderWidth();
#else
Q_ASSERT(window); Q_ASSERT(window);
if (!window) { if (!window) {
return 0; return 0;
} }
return Utilities::getSystemMetric(window, Utilities::SystemMetric::BorderWidth, false); return Utilities::getSystemMetric(window, Utilities::SystemMetric::BorderWidth, false);
#else
Q_UNUSED(window);
return framelessHelper()->getBorderWidth();
#endif #endif
} }
void FramelessWindowsManager::setBorderWidth(const QWindow *window, const int value) void FramelessWindowsManager::setBorderWidth(QWindow *window, const int value)
{ {
#ifdef Q_OS_WINDOWS #ifdef FRAMELESSHELPER_USE_UNIX_VERSION
Q_UNUSED(window);
framelessHelper()->setBorderWidth(value);
#else
Q_ASSERT(window); Q_ASSERT(window);
if (!window) { if (!window) {
return; return;
} }
FramelessHelperWin::setBorderWidth(const_cast<QWindow *>(window), value); FramelessHelperWin::setBorderWidth(window, value);
#else
Q_UNUSED(window);
framelessHelper()->setBorderWidth(value);
#endif #endif
} }
int FramelessWindowsManager::getBorderHeight(const QWindow *window) int FramelessWindowsManager::getBorderHeight(const QWindow *window)
{ {
#ifdef Q_OS_WINDOWS #ifdef FRAMELESSHELPER_USE_UNIX_VERSION
Q_UNUSED(window);
return framelessHelper()->getBorderHeight();
#else
Q_ASSERT(window); Q_ASSERT(window);
if (!window) { if (!window) {
return 0; return 0;
} }
return Utilities::getSystemMetric(window, Utilities::SystemMetric::BorderHeight, false); return Utilities::getSystemMetric(window, Utilities::SystemMetric::BorderHeight, false);
#else
Q_UNUSED(window);
return framelessHelper()->getBorderHeight();
#endif #endif
} }
void FramelessWindowsManager::setBorderHeight(const QWindow *window, const int value) void FramelessWindowsManager::setBorderHeight(QWindow *window, const int value)
{ {
#ifdef Q_OS_WINDOWS #ifdef FRAMELESSHELPER_USE_UNIX_VERSION
Q_UNUSED(window);
framelessHelper()->setBorderHeight(value);
#else
Q_ASSERT(window); Q_ASSERT(window);
if (!window) { if (!window) {
return; return;
} }
FramelessHelperWin::setBorderHeight(const_cast<QWindow *>(window), value); FramelessHelperWin::setBorderHeight(window, value);
#else
Q_UNUSED(window);
framelessHelper()->setBorderHeight(value);
#endif #endif
} }
int FramelessWindowsManager::getTitleBarHeight(const QWindow *window) int FramelessWindowsManager::getTitleBarHeight(const QWindow *window)
{ {
#ifdef Q_OS_WINDOWS #ifdef FRAMELESSHELPER_USE_UNIX_VERSION
Q_UNUSED(window);
return framelessHelper()->getTitleBarHeight();
#else
Q_ASSERT(window); Q_ASSERT(window);
if (!window) { if (!window) {
return 0; return 0;
} }
return Utilities::getSystemMetric(window, Utilities::SystemMetric::TitleBarHeight, false); return Utilities::getSystemMetric(window, Utilities::SystemMetric::TitleBarHeight, false);
#else
Q_UNUSED(window);
return framelessHelper()->getTitleBarHeight();
#endif #endif
} }
void FramelessWindowsManager::setTitleBarHeight(const QWindow *window, const int value) void FramelessWindowsManager::setTitleBarHeight(QWindow *window, const int value)
{ {
#ifdef Q_OS_WINDOWS #ifdef FRAMELESSHELPER_USE_UNIX_VERSION
Q_UNUSED(window);
framelessHelper()->setTitleBarHeight(value);
#else
Q_ASSERT(window); Q_ASSERT(window);
if (!window) { if (!window) {
return; return;
} }
FramelessHelperWin::setTitleBarHeight(const_cast<QWindow *>(window), value); FramelessHelperWin::setTitleBarHeight(window, value);
#else
Q_UNUSED(window);
framelessHelper()->setTitleBarHeight(value);
#endif #endif
} }
@ -162,22 +167,22 @@ bool FramelessWindowsManager::getResizable(const QWindow *window)
if (!window) { if (!window) {
return false; return false;
} }
#ifdef Q_OS_WINDOWS #ifdef FRAMELESSHELPER_USE_UNIX_VERSION
return !Utilities::isWindowFixedSize(window);
#else
return framelessHelper()->getResizable(window); return framelessHelper()->getResizable(window);
#else
return !Utilities::isWindowFixedSize(window);
#endif #endif
} }
void FramelessWindowsManager::setResizable(const QWindow *window, const bool value) void FramelessWindowsManager::setResizable(QWindow *window, const bool value)
{ {
Q_ASSERT(window); Q_ASSERT(window);
if (!window) { if (!window) {
return; return;
} }
#ifdef Q_OS_WINDOWS #ifdef FRAMELESSHELPER_USE_UNIX_VERSION
const_cast<QWindow *>(window)->setFlag(Qt::MSWindowsFixedSizeDialogHint, !value);
#else
framelessHelper()->setResizable(window, value); framelessHelper()->setResizable(window, value);
#else
window->setFlag(Qt::MSWindowsFixedSizeDialogHint, !value);
#endif #endif
} }

View File

@ -1,7 +1,7 @@
/* /*
* MIT License * MIT License
* *
* Copyright (C) 2020 by wangwenx190 (Yuhang Zhao) * Copyright (C) 2021 by wangwenx190 (Yuhang Zhao)
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@ -32,7 +32,7 @@ QT_FORWARD_DECLARE_CLASS(QObject)
QT_FORWARD_DECLARE_CLASS(QWindow) QT_FORWARD_DECLARE_CLASS(QWindow)
QT_END_NAMESPACE QT_END_NAMESPACE
class FRAMELESSHELPER_EXPORT FramelessWindowsManager class FRAMELESSHELPER_API FramelessWindowsManager
{ {
Q_DISABLE_COPY_MOVE(FramelessWindowsManager) Q_DISABLE_COPY_MOVE(FramelessWindowsManager)
@ -40,19 +40,19 @@ public:
explicit FramelessWindowsManager(); explicit FramelessWindowsManager();
~FramelessWindowsManager() = default; ~FramelessWindowsManager() = default;
static void addWindow(const QWindow *window); static void addWindow(QWindow *window);
static void addIgnoreObject(const QWindow *window, QObject *object); static void setHitTestVisible(QWindow *window, QObject *object, const bool value = true);
static int getBorderWidth(const QWindow *window); static int getBorderWidth(const QWindow *window);
static void setBorderWidth(const QWindow *window, const int value); static void setBorderWidth(QWindow *window, const int value);
static int getBorderHeight(const QWindow *window); static int getBorderHeight(const QWindow *window);
static void setBorderHeight(const QWindow *window, const int value); static void setBorderHeight(QWindow *window, const int value);
static int getTitleBarHeight(const QWindow *window); static int getTitleBarHeight(const QWindow *window);
static void setTitleBarHeight(const QWindow *window, const int value); static void setTitleBarHeight(QWindow *window, const int value);
static bool getResizable(const QWindow *window); static bool getResizable(const QWindow *window);
static void setResizable(const QWindow *window, const bool value = true); static void setResizable(QWindow *window, const bool value = true);
}; };

View File

@ -9,7 +9,7 @@ DEFINES += \
QT_NO_CAST_TO_ASCII \ QT_NO_CAST_TO_ASCII \
QT_NO_KEYWORDS \ QT_NO_KEYWORDS \
QT_DEPRECATED_WARNINGS \ QT_DEPRECATED_WARNINGS \
QT_DISABLE_DEPRECATED_BEFORE=0x060000 \ QT_DISABLE_DEPRECATED_BEFORE=0x060100 \
FRAMELESSHELPER_BUILD_LIBRARY FRAMELESSHELPER_BUILD_LIBRARY
HEADERS += \ HEADERS += \
framelesshelper_global.h \ framelesshelper_global.h \

View File

@ -67,50 +67,87 @@ bool Utilities::isWindowFixedSize(const QWindow *window)
return false; return false;
} }
bool Utilities::isMouseInSpecificObjects(const QPointF &mousePos, const QObjectList &objects, const qreal dpr) QPointF Utilities::getGlobalMousePosition(const QWindow *window)
{ {
if (mousePos.isNull()) { if (window) {
qWarning() << "Mouse position point is null."; return (QCursor::pos(window->screen()) * window->devicePixelRatio());
} else {
const qreal dpr = 1.0; // TODO
return (QCursor::pos() * dpr);
}
}
bool Utilities::isHitTestVisible(const QWindow *window)
{
Q_ASSERT(window);
if (!window) {
return false; return false;
} }
if (objects.isEmpty()) { QObjectList objs = {};
qWarning() << "Object list is empty."; const auto target = qvariant_cast<const QObject *>(window->property(_flh_global::_flh_nativeParent_flag));
objs = target ? target->findChildren<QObject *>() : window->findChildren<QObject *>();
if (objs.isEmpty()) {
return false; return false;
} }
for (auto &&object : qAsConst(objects)) { for (auto &&obj : qAsConst(objs)) {
if (!object) { if (!obj || !(obj->isWidgetType() || obj->inherits("QQuickItem"))) {
qWarning() << "Object pointer is null.";
continue; continue;
} }
if (!obj->property(_flh_global::_flh_hitTestVisible_flag).toBool() || !obj->property("visible").toBool()) {
continue;
}
const QPointF originPoint = mapOriginPointToWindow(obj);
const qreal width = obj->property("width").toReal();
const qreal height = obj->property("height").toReal();
const qreal dpr = window->devicePixelRatio();
const QRectF rect = {originPoint.x() * dpr, originPoint.y() * dpr, width * dpr, height * dpr};
if (rect.contains(getGlobalMousePosition(window))) {
return true;
}
}
return false;
}
QObject *Utilities::getNativeParent(const QObject *object)
{
Q_ASSERT(object);
if (!object) {
return nullptr;
}
if (!object->isWidgetType() && !object->inherits("QQuickItem")) { if (!object->isWidgetType() && !object->inherits("QQuickItem")) {
qWarning() << object << "is not a QWidget or QQuickItem!"; qWarning() << object << "is not a QWidget or a QQuickItem.";
continue; return nullptr;
} }
if (!object->property("visible").toBool()) { QObject *parent = object->parent();
qDebug() << "Skipping invisible object" << object; while (parent) {
continue; QObject *p = parent->parent();
if (!p) {
return parent;
} }
const auto mapOriginPointToWindow = [](const QObject *obj) -> QPointF { if (p->isWindowType()) {
Q_ASSERT(obj); return parent;
if (!obj) { }
parent = p;
}
return parent;
}
QPointF Utilities::mapOriginPointToWindow(const QObject *object)
{
Q_ASSERT(object);
if (!object) {
return {}; return {};
} }
QPointF point = {obj->property("x").toReal(), obj->property("y").toReal()}; if (!object->isWidgetType() && !object->inherits("QQuickItem")) {
for (QObject *parent = obj->parent(); parent; parent = parent->parent()) { qWarning() << object << "is not a QWidget or a QQuickItem.";
return {};
}
QPointF point = {object->property("x").toReal(), object->property("y").toReal()};
for (QObject *parent = object->parent(); parent; parent = parent->parent()) {
point += {parent->property("x").toReal(), parent->property("y").toReal()}; point += {parent->property("x").toReal(), parent->property("y").toReal()};
if (parent->isWindowType()) { if (parent->isWindowType()) {
break; break;
} }
} }
return point; return point;
};
const QPointF originPoint = mapOriginPointToWindow(object);
const qreal width = object->property("width").toReal();
const qreal height = object->property("height").toReal();
const QRectF rect = {originPoint.x() * dpr, originPoint.y() * dpr, width * dpr, height * dpr};
if (rect.contains(mousePos)) {
return true;
}
}
return false;
} }

View File

@ -38,42 +38,48 @@ enum class SystemMetric
}; };
// Common // Common
FRAMELESSHELPER_EXPORT int getSystemMetric(const QWindow *window, const SystemMetric metric, const bool dpiAware, const bool forceSystemValue = false); FRAMELESSHELPER_API int getSystemMetric(const QWindow *window, const SystemMetric metric, const bool dpiAware, const bool forceSystemValue = false);
FRAMELESSHELPER_EXPORT bool isLightThemeEnabled(); FRAMELESSHELPER_API bool isLightThemeEnabled();
FRAMELESSHELPER_EXPORT bool isDarkThemeEnabled(); FRAMELESSHELPER_API bool isDarkThemeEnabled();
FRAMELESSHELPER_EXPORT QWindow *findWindow(const WId winId); FRAMELESSHELPER_API QWindow *findWindow(const WId winId);
FRAMELESSHELPER_EXPORT bool shouldUseNativeTitleBar(); FRAMELESSHELPER_API bool shouldUseNativeTitleBar();
FRAMELESSHELPER_EXPORT bool isWindowFixedSize(const QWindow *window); FRAMELESSHELPER_API bool isWindowFixedSize(const QWindow *window);
FRAMELESSHELPER_EXPORT bool isMouseInSpecificObjects(const QPointF &mousePos, const QObjectList &objects, const qreal dpr = 1.0); FRAMELESSHELPER_API QPointF getGlobalMousePosition(const QWindow *window);
FRAMELESSHELPER_EXPORT QColor getNativeWindowFrameColor(const bool isActive = true); FRAMELESSHELPER_API bool isHitTestVisible(const QWindow *window);
FRAMELESSHELPER_API QColor getNativeWindowFrameColor(const bool isActive = true);
FRAMELESSHELPER_API QObject *getNativeParent(const QObject *object);
FRAMELESSHELPER_API QPointF mapOriginPointToWindow(const QObject *object);
#ifdef Q_OS_WINDOWS #ifdef Q_OS_WINDOWS
// Windows specific // Windows specific
FRAMELESSHELPER_EXPORT bool isWin7OrGreater(); FRAMELESSHELPER_API bool isWin7OrGreater();
FRAMELESSHELPER_EXPORT bool isWin8OrGreater(); FRAMELESSHELPER_API bool isWin8OrGreater();
FRAMELESSHELPER_EXPORT bool isWin8Point1OrGreater(); FRAMELESSHELPER_API bool isWin8Point1OrGreater();
FRAMELESSHELPER_EXPORT bool isWin10OrGreater(); FRAMELESSHELPER_API bool isWin10OrGreater();
FRAMELESSHELPER_EXPORT bool isWin10OrGreater(const int subVer); FRAMELESSHELPER_API bool isWin10OrGreater(const int subVer);
FRAMELESSHELPER_EXPORT bool isDwmBlurAvailable(); FRAMELESSHELPER_API bool isDwmBlurAvailable();
FRAMELESSHELPER_EXPORT bool isColorizationEnabled(); FRAMELESSHELPER_API bool isColorizationEnabled();
FRAMELESSHELPER_EXPORT QColor getColorizationColor(); FRAMELESSHELPER_API QColor getColorizationColor();
FRAMELESSHELPER_EXPORT void triggerFrameChange(const QWindow *window); FRAMELESSHELPER_API void triggerFrameChange(const QWindow *window);
FRAMELESSHELPER_EXPORT void updateFrameMargins(const QWindow *window, const bool reset); FRAMELESSHELPER_API void updateFrameMargins(const QWindow *window, const bool reset);
FRAMELESSHELPER_EXPORT void updateQtFrameMargins(QWindow *window, const bool enable); FRAMELESSHELPER_API void updateQtFrameMargins(QWindow *window, const bool enable);
FRAMELESSHELPER_EXPORT quint32 getWindowDpi(const QWindow *window); FRAMELESSHELPER_API quint32 getWindowDpi(const QWindow *window);
FRAMELESSHELPER_EXPORT QMargins getWindowNativeFrameMargins(const QWindow *window); FRAMELESSHELPER_API QMargins getWindowNativeFrameMargins(const QWindow *window);
FRAMELESSHELPER_EXPORT void displaySystemMenu(const QWindow *window, const QPoint &pos = {}); FRAMELESSHELPER_API void displaySystemMenu(const QWindow *window, const QPoint &pos = {});
#endif #endif
} }