forked from github_mirror/framelesshelper
parent
f68665298b
commit
d46ec0c1b6
|
@ -13,6 +13,14 @@ if(NOT (CMAKE_BUILD_TYPE STREQUAL "Debug") AND NOT DEFINED CMAKE_INTERPROCEDURAL
|
|||
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION ON)
|
||||
endif()
|
||||
|
||||
if(NOT DEFINED CMAKE_DEBUG_POSTFIX)
|
||||
if(WIN32)
|
||||
set(CMAKE_DEBUG_POSTFIX d)
|
||||
else()
|
||||
set(CMAKE_DEBUG_POSTFIX _debug)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
set(CMAKE_CXX_EXTENSIONS OFF)
|
||||
|
|
|
@ -6,8 +6,8 @@
|
|||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>518</width>
|
||||
<height>368</height>
|
||||
<width>800</width>
|
||||
<height>600</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
|
|
|
@ -61,7 +61,7 @@ void MainWindow::changeEvent(QEvent *event)
|
|||
bool shouldUpdate = false;
|
||||
if (event->type() == QEvent::WindowStateChange) {
|
||||
#ifdef Q_OS_WINDOWS
|
||||
if (Utilities::isWin10OrGreater()) {
|
||||
if (Utilities::isWindowFrameBorderVisible()) {
|
||||
if (isMaximized() || isFullScreen()) {
|
||||
setContentsMargins(0, 0, 0, 0);
|
||||
} else if (!isMinimized()) {
|
||||
|
@ -91,7 +91,7 @@ void MainWindow::initFramelessHelperOnce()
|
|||
void MainWindow::resetContentsMargins()
|
||||
{
|
||||
#ifdef Q_OS_WINDOWS
|
||||
if (Utilities::isWin10OrGreater()) {
|
||||
if (Utilities::isWindowFrameBorderVisible()) {
|
||||
setContentsMargins(0, 1, 0, 0);
|
||||
}
|
||||
#endif
|
||||
|
@ -101,7 +101,7 @@ void MainWindow::paintEvent(QPaintEvent *event)
|
|||
{
|
||||
QMainWindow::paintEvent(event);
|
||||
#ifdef Q_OS_WINDOWS
|
||||
if ((windowState() == Qt::WindowNoState) && Utilities::isWin10OrGreater() && !Utilities::isWin11OrGreater()) {
|
||||
if ((windowState() == Qt::WindowNoState) && Utilities::isWindowFrameBorderVisible() && !Utilities::isWin11OrGreater()) {
|
||||
QPainter painter(this);
|
||||
painter.save();
|
||||
QPen pen = {};
|
||||
|
|
|
@ -111,7 +111,7 @@ void Widget::changeEvent(QEvent *event)
|
|||
bool shouldUpdate = false;
|
||||
if (event->type() == QEvent::WindowStateChange) {
|
||||
#ifdef Q_OS_WINDOWS
|
||||
if (Utilities::isWin10OrGreater()) {
|
||||
if (Utilities::isWindowFrameBorderVisible()) {
|
||||
if (isMaximized() || isFullScreen()) {
|
||||
setContentsMargins(0, 0, 0, 0);
|
||||
} else if (!isMinimized()) {
|
||||
|
@ -133,7 +133,7 @@ void Widget::paintEvent(QPaintEvent *event)
|
|||
{
|
||||
QWidget::paintEvent(event);
|
||||
#ifdef Q_OS_WINDOWS
|
||||
if ((windowState() == Qt::WindowNoState) && Utilities::isWin10OrGreater() && !Utilities::isWin11OrGreater()) {
|
||||
if ((windowState() == Qt::WindowNoState) && Utilities::isWindowFrameBorderVisible() && !Utilities::isWin11OrGreater()) {
|
||||
QPainter painter(this);
|
||||
painter.save();
|
||||
QPen pen = {};
|
||||
|
@ -333,7 +333,7 @@ void Widget::updateSystemButtonIcons()
|
|||
void Widget::resetContentsMargins()
|
||||
{
|
||||
#ifdef Q_OS_WINDOWS
|
||||
if (Utilities::isWin10OrGreater()) {
|
||||
if (Utilities::isWindowFrameBorderVisible()) {
|
||||
setContentsMargins(0, 1, 0, 0);
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -23,12 +23,27 @@
|
|||
*/
|
||||
|
||||
#include "framelesshelper.h"
|
||||
#include <QtCore/qmutex.h>
|
||||
#include <QtGui/qevent.h>
|
||||
#include <QtGui/qwindow.h>
|
||||
#include "utilities.h"
|
||||
|
||||
FRAMELESSHELPER_BEGIN_NAMESPACE
|
||||
|
||||
struct UnixHelper
|
||||
{
|
||||
QMutex mutex = {};
|
||||
QWindowList acceptableWindows = {};
|
||||
|
||||
explicit UnixHelper() = default;
|
||||
~UnixHelper() = default;
|
||||
|
||||
private:
|
||||
Q_DISABLE_COPY_MOVE(UnixHelper)
|
||||
};
|
||||
|
||||
Q_GLOBAL_STATIC(UnixHelper, g_unixHelper)
|
||||
|
||||
FramelessHelper::FramelessHelper(QObject *parent) : QObject(parent) {}
|
||||
|
||||
FramelessHelper::~FramelessHelper() = default;
|
||||
|
@ -39,6 +54,13 @@ void FramelessHelper::addWindow(QWindow *window)
|
|||
if (!window) {
|
||||
return;
|
||||
}
|
||||
g_unixHelper()->mutex.lock();
|
||||
if (g_unixHelper()->acceptableWindows.contains(window)) {
|
||||
g_unixHelper()->mutex.unlock();
|
||||
return;
|
||||
}
|
||||
g_unixHelper()->acceptableWindows.append(window);
|
||||
g_unixHelper()->mutex.unlock();
|
||||
window->setFlags(window->flags() | Qt::FramelessWindowHint);
|
||||
window->installEventFilter(this);
|
||||
}
|
||||
|
@ -49,6 +71,13 @@ void FramelessHelper::removeWindow(QWindow *window)
|
|||
if (!window) {
|
||||
return;
|
||||
}
|
||||
g_unixHelper()->mutex.lock();
|
||||
if (!g_unixHelper()->acceptableWindows.contains(window)) {
|
||||
g_unixHelper()->mutex.unlock();
|
||||
return;
|
||||
}
|
||||
g_unixHelper()->acceptableWindows.removeAll(window);
|
||||
g_unixHelper()->mutex.unlock();
|
||||
window->removeEventFilter(this);
|
||||
window->setFlags(window->flags() & ~Qt::FramelessWindowHint);
|
||||
}
|
||||
|
@ -70,6 +99,12 @@ bool FramelessHelper::eventFilter(QObject *object, QEvent *event)
|
|||
return false;
|
||||
}
|
||||
const auto window = qobject_cast<QWindow *>(object);
|
||||
g_unixHelper()->mutex.lock();
|
||||
if (!g_unixHelper()->acceptableWindows.contains(window)) {
|
||||
g_unixHelper()->mutex.unlock();
|
||||
return false;
|
||||
}
|
||||
g_unixHelper()->mutex.unlock();
|
||||
if (Utilities::isWindowFixedSize(window)) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -95,19 +95,9 @@ FRAMELESSHELPER_BEGIN_NAMESPACE
|
|||
|
||||
Q_NAMESPACE_EXPORT(FRAMELESSHELPER_API)
|
||||
|
||||
[[maybe_unused]] static constexpr const int kDefaultResizeBorderThicknessClassic = 4;
|
||||
[[maybe_unused]] static constexpr const int kDefaultResizeBorderThicknessAero = 8;
|
||||
[[maybe_unused]] static constexpr const int kDefaultResizeBorderThickness = 8;
|
||||
[[maybe_unused]] static constexpr const int kDefaultCaptionHeight = 23;
|
||||
[[maybe_unused]] static constexpr const int kDefaultTitleBarHeight = 30;
|
||||
[[maybe_unused]] static constexpr const int kDefaultWindowFrameBorderThickness = 1;
|
||||
|
||||
enum class DwmColorizationArea : int
|
||||
{
|
||||
None = 0,
|
||||
StartMenu_TaskBar_ActionCenter = 1,
|
||||
TitleBar_WindowBorder = 2,
|
||||
All = 3
|
||||
};
|
||||
Q_ENUM_NS(DwmColorizationArea)
|
||||
|
||||
FRAMELESSHELPER_END_NAMESPACE
|
||||
|
|
|
@ -30,37 +30,37 @@
|
|||
#include <QtCore/qcoreapplication.h>
|
||||
#include <QtGui/qwindow.h>
|
||||
#include "framelesswindowsmanager.h"
|
||||
#include "framelesswindowsmanager_p.h"
|
||||
#include "utilities.h"
|
||||
#include "framelesshelper_windows.h"
|
||||
|
||||
FRAMELESSHELPER_BEGIN_NAMESPACE
|
||||
|
||||
struct FramelessHelperWinData
|
||||
struct Win32Helper
|
||||
{
|
||||
QMutex mutex = {};
|
||||
QScopedPointer<FramelessHelperWin> instance;
|
||||
QList<WId> acceptableWinIds = {};
|
||||
QScopedPointer<FramelessHelperWin> nativeEventFilter;
|
||||
QWindowList acceptableWindows = {};
|
||||
QHash<WId, QWindow *> windowMapping = {};
|
||||
QHash<HWND, WNDPROC> qtWindowProcs = {};
|
||||
|
||||
explicit FramelessHelperWinData() = default;
|
||||
~FramelessHelperWinData() = default;
|
||||
explicit Win32Helper() = default;
|
||||
~Win32Helper() = default;
|
||||
|
||||
private:
|
||||
Q_DISABLE_COPY_MOVE(FramelessHelperWinData)
|
||||
Q_DISABLE_COPY_MOVE(Win32Helper)
|
||||
};
|
||||
|
||||
Q_GLOBAL_STATIC(FramelessHelperWinData, g_helper)
|
||||
Q_GLOBAL_STATIC(Win32Helper, g_win32Helper)
|
||||
|
||||
[[nodiscard]] static inline LRESULT CALLBACK HookWindowProc
|
||||
(const HWND hWnd, const UINT uMsg, const WPARAM wParam, const LPARAM lParam)
|
||||
{
|
||||
g_helper()->mutex.lock();
|
||||
if (!g_helper()->qtWindowProcs.contains(hWnd)) {
|
||||
g_helper()->mutex.unlock();
|
||||
g_win32Helper()->mutex.lock();
|
||||
if (!g_win32Helper()->qtWindowProcs.contains(hWnd)) {
|
||||
g_win32Helper()->mutex.unlock();
|
||||
return DefWindowProcW(hWnd, uMsg, wParam, lParam);
|
||||
}
|
||||
g_helper()->mutex.unlock();
|
||||
g_win32Helper()->mutex.unlock();
|
||||
const auto winId = reinterpret_cast<WId>(hWnd);
|
||||
const auto getGlobalPosFromMouse = [lParam]() -> QPointF {
|
||||
return {qreal(GET_X_LPARAM(lParam)), qreal(GET_Y_LPARAM(lParam))};
|
||||
|
@ -75,7 +75,7 @@ Q_GLOBAL_STATIC(FramelessHelperWinData, g_helper)
|
|||
const int frameSizeX = Utilities::getResizeBorderThickness(winId, true, true);
|
||||
const int frameSizeY = Utilities::getResizeBorderThickness(winId, false, true);
|
||||
const int titleBarHeight = Utilities::getTitleBarHeight(winId, true);
|
||||
const int horizontalOffset = ((maxOrFull || !Utilities::isWin10OrGreater()) ? 0 : frameSizeX);
|
||||
const int horizontalOffset = ((maxOrFull || !Utilities::isWindowFrameBorderVisible()) ? 0 : frameSizeX);
|
||||
const int verticalOffset = (maxOrFull ? titleBarHeight : (titleBarHeight - frameSizeY));
|
||||
return {qreal(rect.left + horizontalOffset), qreal(rect.top + verticalOffset)};
|
||||
};
|
||||
|
@ -108,9 +108,9 @@ Q_GLOBAL_STATIC(FramelessHelperWinData, g_helper)
|
|||
// entering Qt's own handling logic.
|
||||
return 0; // Return 0 means we have handled this event.
|
||||
}
|
||||
g_helper()->mutex.lock();
|
||||
const WNDPROC originalWindowProc = g_helper()->qtWindowProcs.value(hWnd);
|
||||
g_helper()->mutex.unlock();
|
||||
g_win32Helper()->mutex.lock();
|
||||
const WNDPROC originalWindowProc = g_win32Helper()->qtWindowProcs.value(hWnd);
|
||||
g_win32Helper()->mutex.unlock();
|
||||
Q_ASSERT(originalWindowProc);
|
||||
if (originalWindowProc) {
|
||||
// Hand over to Qt's original window proc function for events we are not
|
||||
|
@ -128,8 +128,8 @@ Q_GLOBAL_STATIC(FramelessHelperWinData, g_helper)
|
|||
return false;
|
||||
}
|
||||
const auto hwnd = reinterpret_cast<HWND>(winId);
|
||||
QMutexLocker locker(&g_helper()->mutex);
|
||||
if (g_helper()->qtWindowProcs.contains(hwnd)) {
|
||||
QMutexLocker locker(&g_win32Helper()->mutex);
|
||||
if (g_win32Helper()->qtWindowProcs.contains(hwnd)) {
|
||||
return false;
|
||||
}
|
||||
SetLastError(ERROR_SUCCESS);
|
||||
|
@ -144,7 +144,7 @@ Q_GLOBAL_STATIC(FramelessHelperWinData, g_helper)
|
|||
qWarning() << Utilities::getSystemErrorMessage(QStringLiteral("SetWindowLongPtrW"));
|
||||
return false;
|
||||
}
|
||||
g_helper()->qtWindowProcs.insert(hwnd, originalWindowProc);
|
||||
g_win32Helper()->qtWindowProcs.insert(hwnd, originalWindowProc);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -155,11 +155,11 @@ Q_GLOBAL_STATIC(FramelessHelperWinData, g_helper)
|
|||
return false;
|
||||
}
|
||||
const auto hwnd = reinterpret_cast<HWND>(winId);
|
||||
QMutexLocker locker(&g_helper()->mutex);
|
||||
if (!g_helper()->qtWindowProcs.contains(hwnd)) {
|
||||
QMutexLocker locker(&g_win32Helper()->mutex);
|
||||
if (!g_win32Helper()->qtWindowProcs.contains(hwnd)) {
|
||||
return false;
|
||||
}
|
||||
const WNDPROC originalWindowProc = g_helper()->qtWindowProcs.value(hwnd);
|
||||
const WNDPROC originalWindowProc = g_win32Helper()->qtWindowProcs.value(hwnd);
|
||||
Q_ASSERT(originalWindowProc);
|
||||
if (!originalWindowProc) {
|
||||
return false;
|
||||
|
@ -169,7 +169,7 @@ Q_GLOBAL_STATIC(FramelessHelperWinData, g_helper)
|
|||
qWarning() << Utilities::getSystemErrorMessage(QStringLiteral("SetWindowLongPtrW"));
|
||||
return false;
|
||||
}
|
||||
g_helper()->qtWindowProcs.remove(hwnd);
|
||||
g_win32Helper()->qtWindowProcs.remove(hwnd);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -186,18 +186,19 @@ void FramelessHelperWin::addWindow(QWindow *window)
|
|||
if (!window) {
|
||||
return;
|
||||
}
|
||||
const WId winId = window->winId();
|
||||
g_helper()->mutex.lock();
|
||||
if (g_helper()->acceptableWinIds.contains(winId)) {
|
||||
g_helper()->mutex.unlock();
|
||||
g_win32Helper()->mutex.lock();
|
||||
if (g_win32Helper()->acceptableWindows.contains(window)) {
|
||||
g_win32Helper()->mutex.unlock();
|
||||
return;
|
||||
}
|
||||
g_helper()->acceptableWinIds.append(winId);
|
||||
if (g_helper()->instance.isNull()) {
|
||||
g_helper()->instance.reset(new FramelessHelperWin);
|
||||
qApp->installNativeEventFilter(g_helper()->instance.data());
|
||||
g_win32Helper()->acceptableWindows.append(window);
|
||||
const WId winId = window->winId();
|
||||
g_win32Helper()->windowMapping.insert(winId, window);
|
||||
if (g_win32Helper()->nativeEventFilter.isNull()) {
|
||||
g_win32Helper()->nativeEventFilter.reset(new FramelessHelperWin);
|
||||
qApp->installNativeEventFilter(g_win32Helper()->nativeEventFilter.data());
|
||||
}
|
||||
g_helper()->mutex.unlock();
|
||||
g_win32Helper()->mutex.unlock();
|
||||
Utilities::fixupQtInternals(winId);
|
||||
Utilities::updateInternalWindowFrameMargins(window, true);
|
||||
Utilities::updateWindowFrameMargins(winId, false);
|
||||
|
@ -214,14 +215,15 @@ void FramelessHelperWin::removeWindow(QWindow *window)
|
|||
if (!window) {
|
||||
return;
|
||||
}
|
||||
const WId winId = window->winId();
|
||||
g_helper()->mutex.lock();
|
||||
if (!g_helper()->acceptableWinIds.contains(winId)) {
|
||||
g_helper()->mutex.unlock();
|
||||
g_win32Helper()->mutex.lock();
|
||||
if (!g_win32Helper()->acceptableWindows.contains(window)) {
|
||||
g_win32Helper()->mutex.unlock();
|
||||
return;
|
||||
}
|
||||
g_helper()->acceptableWinIds.removeAll(winId);
|
||||
g_helper()->mutex.unlock();
|
||||
g_win32Helper()->acceptableWindows.removeAll(window);
|
||||
const WId winId = window->winId();
|
||||
g_win32Helper()->windowMapping.remove(winId);
|
||||
g_win32Helper()->mutex.unlock();
|
||||
if (!uninstallWindowHook(winId)) {
|
||||
qWarning() << "Failed to un-hook the window proc function.";
|
||||
}
|
||||
|
@ -250,19 +252,13 @@ bool FramelessHelperWin::nativeEventFilter(const QByteArray &eventType, void *me
|
|||
return false;
|
||||
}
|
||||
const WId winId = reinterpret_cast<WId>(msg->hwnd);
|
||||
g_helper()->mutex.lock();
|
||||
if (!g_helper()->acceptableWinIds.contains(winId)) {
|
||||
g_helper()->mutex.unlock();
|
||||
g_win32Helper()->mutex.lock();
|
||||
if (!g_win32Helper()->windowMapping.contains(winId)) {
|
||||
g_win32Helper()->mutex.unlock();
|
||||
return false;
|
||||
}
|
||||
g_helper()->mutex.unlock();
|
||||
const FramelessManagerPrivate * const manager = FramelessManagerPrivate::instance();
|
||||
const QUuid id = manager->findIdByWinId(winId);
|
||||
Q_ASSERT(!id.isNull());
|
||||
if (id.isNull()) {
|
||||
return false;
|
||||
}
|
||||
QWindow * const window = manager->findWindowById(id);
|
||||
QWindow * const window = g_win32Helper()->windowMapping.value(winId);
|
||||
g_win32Helper()->mutex.unlock();
|
||||
Q_ASSERT(window);
|
||||
if (!window) {
|
||||
return false;
|
||||
|
@ -359,7 +355,7 @@ bool FramelessHelperWin::nativeEventFilter(const QByteArray &eventType, void *me
|
|||
const auto clientRect = ((static_cast<BOOL>(msg->wParam) == FALSE)
|
||||
? reinterpret_cast<LPRECT>(msg->lParam)
|
||||
: &(reinterpret_cast<LPNCCALCSIZE_PARAMS>(msg->lParam))->rgrc[0]);
|
||||
if (Utilities::isWin10OrGreater()) {
|
||||
if (Utilities::isWindowFrameBorderVisible()) {
|
||||
// Store the original top before the default window proc applies the default frame.
|
||||
const LONG originalTop = clientRect->top;
|
||||
// Apply the default frame.
|
||||
|
@ -385,7 +381,7 @@ bool FramelessHelperWin::nativeEventFilter(const QByteArray &eventType, void *me
|
|||
// a window when it's maximized unless you restore it).
|
||||
const int frameSizeY = Utilities::getResizeBorderThickness(winId, false, true);
|
||||
clientRect->top += frameSizeY;
|
||||
if (!Utilities::isWin10OrGreater()) {
|
||||
if (!Utilities::isWindowFrameBorderVisible()) {
|
||||
clientRect->bottom -= frameSizeY;
|
||||
const int frameSizeX = Utilities::getResizeBorderThickness(winId, true, true);
|
||||
clientRect->left += frameSizeX;
|
||||
|
@ -598,8 +594,8 @@ bool FramelessHelperWin::nativeEventFilter(const QByteArray &eventType, void *me
|
|||
const bool full = Utilities::isFullScreen(winId);
|
||||
const int frameSizeY = Utilities::getResizeBorderThickness(winId, false, true);
|
||||
const bool isTop = (localPos.y < frameSizeY);
|
||||
const bool isTitleBar = false; // ### TODO
|
||||
if (Utilities::isWin10OrGreater()) {
|
||||
static constexpr const bool isTitleBar = false;
|
||||
if (Utilities::isWindowFrameBorderVisible()) {
|
||||
// This will handle the left, right and bottom parts of the frame
|
||||
// because we didn't change them.
|
||||
const LRESULT originalRet = DefWindowProcW(msg->hwnd, WM_NCHITTEST, 0, msg->lParam);
|
||||
|
@ -712,7 +708,7 @@ bool FramelessHelperWin::nativeEventFilter(const QByteArray &eventType, void *me
|
|||
default:
|
||||
break;
|
||||
}
|
||||
if (!Utilities::isWin10OrGreater()) {
|
||||
if (!Utilities::isWindowFrameBorderVisible()) {
|
||||
switch (msg->message) {
|
||||
case WM_NCUAHDRAWCAPTION:
|
||||
case WM_NCUAHDRAWFRAME: {
|
||||
|
|
|
@ -78,7 +78,7 @@ qreal FramelessQuickUtils::titleBarHeight()
|
|||
bool FramelessQuickUtils::frameBorderVisible()
|
||||
{
|
||||
#ifdef Q_OS_WINDOWS
|
||||
return (Utilities::isWin10OrGreater() && !Utilities::isWin11OrGreater());
|
||||
return (Utilities::isWindowFrameBorderVisible() && !Utilities::isWin11OrGreater());
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
|
|
|
@ -41,6 +41,9 @@ class FRAMELESSHELPER_API FramelessQuickHelper : public QObject
|
|||
#ifdef QML_NAMED_ELEMENT
|
||||
QML_NAMED_ELEMENT(FramelessHelper)
|
||||
#endif
|
||||
#ifdef QML_SINGLETON
|
||||
QML_SINGLETON
|
||||
#endif
|
||||
|
||||
public:
|
||||
explicit FramelessQuickHelper(QObject *parent = nullptr);
|
||||
|
@ -56,6 +59,9 @@ class FRAMELESSHELPER_API FramelessQuickUtils : public QObject
|
|||
Q_DISABLE_COPY_MOVE(FramelessQuickUtils)
|
||||
#ifdef QML_NAMED_ELEMENT
|
||||
QML_NAMED_ELEMENT(FramelessUtils)
|
||||
#endif
|
||||
#ifdef QML_SINGLETON
|
||||
QML_SINGLETON
|
||||
#endif
|
||||
Q_PROPERTY(qreal titleBarHeight READ titleBarHeight CONSTANT FINAL)
|
||||
Q_PROPERTY(bool frameBorderVisible READ frameBorderVisible CONSTANT FINAL)
|
||||
|
|
|
@ -26,8 +26,6 @@
|
|||
|
||||
FRAMELESSHELPER_BEGIN_NAMESPACE
|
||||
|
||||
static constexpr const int g_resizeBorderThickness = kDefaultResizeBorderThicknessAero;
|
||||
|
||||
Qt::CursorShape Utilities::calculateCursorShape(const QWindow *window, const QPointF &pos)
|
||||
{
|
||||
Q_ASSERT(window);
|
||||
|
@ -37,18 +35,18 @@ Qt::CursorShape Utilities::calculateCursorShape(const QWindow *window, const QPo
|
|||
if (window->visibility() != QWindow::Windowed) {
|
||||
return Qt::ArrowCursor;
|
||||
}
|
||||
if (((pos.x() < g_resizeBorderThickness) && (pos.y() < g_resizeBorderThickness))
|
||||
|| ((pos.x() >= (window->width() - g_resizeBorderThickness)) && (pos.y() >= (window->height() - g_resizeBorderThickness)))) {
|
||||
if (((pos.x() < kDefaultResizeBorderThickness) && (pos.y() < kDefaultResizeBorderThickness))
|
||||
|| ((pos.x() >= (window->width() - kDefaultResizeBorderThickness)) && (pos.y() >= (window->height() - kDefaultResizeBorderThickness)))) {
|
||||
return Qt::SizeFDiagCursor;
|
||||
}
|
||||
if (((pos.x() >= (window->width() - g_resizeBorderThickness)) && (pos.y() < g_resizeBorderThickness))
|
||||
|| ((pos.x() < g_resizeBorderThickness) && (pos.y() >= (window->height() - g_resizeBorderThickness)))) {
|
||||
if (((pos.x() >= (window->width() - kDefaultResizeBorderThickness)) && (pos.y() < kDefaultResizeBorderThickness))
|
||||
|| ((pos.x() < kDefaultResizeBorderThickness) && (pos.y() >= (window->height() - kDefaultResizeBorderThickness)))) {
|
||||
return Qt::SizeBDiagCursor;
|
||||
}
|
||||
if ((pos.x() < g_resizeBorderThickness) || (pos.x() >= (window->width() - g_resizeBorderThickness))) {
|
||||
if ((pos.x() < kDefaultResizeBorderThickness) || (pos.x() >= (window->width() - kDefaultResizeBorderThickness))) {
|
||||
return Qt::SizeHorCursor;
|
||||
}
|
||||
if ((pos.y() < g_resizeBorderThickness) || (pos.y() >= (window->height() - g_resizeBorderThickness))) {
|
||||
if ((pos.y() < kDefaultResizeBorderThickness) || (pos.y() >= (window->height() - kDefaultResizeBorderThickness))) {
|
||||
return Qt::SizeVerCursor;
|
||||
}
|
||||
return Qt::ArrowCursor;
|
||||
|
@ -64,16 +62,16 @@ Qt::Edges Utilities::calculateWindowEdges(const QWindow *window, const QPointF &
|
|||
return {};
|
||||
}
|
||||
Qt::Edges edges = {};
|
||||
if (pos.x() < g_resizeBorderThickness) {
|
||||
if (pos.x() < kDefaultResizeBorderThickness) {
|
||||
edges |= Qt::LeftEdge;
|
||||
}
|
||||
if (pos.x() >= (window->width() - g_resizeBorderThickness)) {
|
||||
if (pos.x() >= (window->width() - kDefaultResizeBorderThickness)) {
|
||||
edges |= Qt::RightEdge;
|
||||
}
|
||||
if (pos.y() < g_resizeBorderThickness) {
|
||||
if (pos.y() < kDefaultResizeBorderThickness) {
|
||||
edges |= Qt::TopEdge;
|
||||
}
|
||||
if (pos.y() >= (window->height() - g_resizeBorderThickness)) {
|
||||
if (pos.y() >= (window->height() - kDefaultResizeBorderThickness)) {
|
||||
edges |= Qt::BottomEdge;
|
||||
}
|
||||
return edges;
|
||||
|
|
12
utilities.h
12
utilities.h
|
@ -29,6 +29,17 @@
|
|||
|
||||
FRAMELESSHELPER_BEGIN_NAMESPACE
|
||||
|
||||
#ifdef Q_OS_WINDOWS
|
||||
enum class DwmColorizationArea : int
|
||||
{
|
||||
None = 0,
|
||||
StartMenu_TaskBar_ActionCenter = 1,
|
||||
TitleBar_WindowBorder = 2,
|
||||
All = 3
|
||||
};
|
||||
Q_ENUM_NS(DwmColorizationArea)
|
||||
#endif
|
||||
|
||||
namespace Utilities
|
||||
{
|
||||
|
||||
|
@ -66,6 +77,7 @@ FRAMELESSHELPER_API void showSystemMenu(const WId winId, const QPointF &pos);
|
|||
[[nodiscard]] FRAMELESSHELPER_API QColor getFrameBorderColor(const bool active);
|
||||
FRAMELESSHELPER_API void updateWindowFrameBorderColor(const WId winId, const bool dark);
|
||||
FRAMELESSHELPER_API void fixupQtInternals(const WId winId);
|
||||
[[nodiscard]] FRAMELESSHELPER_API bool isWindowFrameBorderVisible();
|
||||
#endif // Q_OS_WINDOWS
|
||||
|
||||
} // namespace Utilities
|
||||
|
|
|
@ -46,6 +46,8 @@ Q_DECLARE_METATYPE(QMargins)
|
|||
|
||||
FRAMELESSHELPER_BEGIN_NAMESPACE
|
||||
|
||||
static const QString successErrorText = QStringLiteral("The operation completed successfully.");
|
||||
|
||||
#if (QT_VERSION < QT_VERSION_CHECK(5, 9, 0))
|
||||
[[nodiscard]] static inline bool isWindowsVersionOrGreater(const DWORD dwMajor, const DWORD dwMinor, const DWORD dwBuild)
|
||||
{
|
||||
|
@ -71,17 +73,21 @@ FRAMELESSHELPER_BEGIN_NAMESPACE
|
|||
return {};
|
||||
}
|
||||
if (code == ERROR_SUCCESS) {
|
||||
return {};
|
||||
return successErrorText;
|
||||
}
|
||||
LPWSTR buf = nullptr;
|
||||
if (FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||
nullptr, code, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), reinterpret_cast<LPWSTR>(&buf), 0, nullptr) == 0) {
|
||||
return {};
|
||||
return QStringLiteral("FormatMessageW() returned empty string.");
|
||||
}
|
||||
const QString message = QStringLiteral("Function %1() failed with error code %2: %3.")
|
||||
.arg(function, QString::number(code), QString::fromWCharArray(buf));
|
||||
QString errorText = QString::fromWCharArray(buf);
|
||||
LocalFree(buf);
|
||||
return message;
|
||||
buf = nullptr;
|
||||
errorText = errorText.trimmed();
|
||||
errorText.remove(QStringLiteral("\\r"));
|
||||
errorText.replace(QStringLiteral("\\n"), QStringLiteral("\n"));
|
||||
return QStringLiteral("Function \"%1()\" failed with error code %2: %3.")
|
||||
.arg(function, QString::number(code), errorText);
|
||||
}
|
||||
|
||||
[[nodiscard]] static inline QString __getSystemErrorMessage(const QString &function, const HRESULT hr)
|
||||
|
@ -91,7 +97,7 @@ FRAMELESSHELPER_BEGIN_NAMESPACE
|
|||
return {};
|
||||
}
|
||||
if (SUCCEEDED(hr)) {
|
||||
return {};
|
||||
return successErrorText;
|
||||
}
|
||||
const DWORD dwError = HRESULT_CODE(hr);
|
||||
return __getSystemErrorMessage(function, dwError);
|
||||
|
@ -248,7 +254,7 @@ void Utilities::updateWindowFrameMargins(const WId winId, const bool reset)
|
|||
if (reset) {
|
||||
return {0, 0, 0, 0};
|
||||
}
|
||||
if (isWin10OrGreater()) {
|
||||
if (isWindowFrameBorderVisible()) {
|
||||
return {0, static_cast<int>(getTitleBarHeight(winId, true)), 0, 0};
|
||||
} else {
|
||||
return {1, 1, 1, 1};
|
||||
|
@ -275,7 +281,7 @@ void Utilities::updateInternalWindowFrameMargins(QWindow *window, const bool ena
|
|||
return {};
|
||||
}
|
||||
const int titleBarHeight = getTitleBarHeight(winId, true);
|
||||
if (isWin10OrGreater()) {
|
||||
if (isWindowFrameBorderVisible()) {
|
||||
return {0, -titleBarHeight, 0, 0};
|
||||
} else {
|
||||
const int frameSizeX = getResizeBorderThickness(winId, true, true);
|
||||
|
@ -286,17 +292,14 @@ void Utilities::updateInternalWindowFrameMargins(QWindow *window, const bool ena
|
|||
const QVariant marginsVar = QVariant::fromValue(margins);
|
||||
window->setProperty("_q_windowsCustomMargins", marginsVar);
|
||||
#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
|
||||
QPlatformWindow *platformWindow = window->handle();
|
||||
if (platformWindow) {
|
||||
if (QPlatformWindow *platformWindow = window->handle()) {
|
||||
QGuiApplication::platformNativeInterface()->setWindowProperty(platformWindow, QStringLiteral("WindowsCustomMargins"), marginsVar);
|
||||
} else {
|
||||
qWarning() << "Failed to retrieve the platform window.";
|
||||
return;
|
||||
}
|
||||
#else
|
||||
auto *platformWindow = dynamic_cast<QNativeInterface::Private::QWindowsWindow *>(
|
||||
window->handle());
|
||||
if (platformWindow) {
|
||||
if (const auto platformWindow = dynamic_cast<QNativeInterface::Private::QWindowsWindow *>(window->handle())) {
|
||||
platformWindow->setCustomMargins(margins);
|
||||
} else {
|
||||
qWarning() << "Failed to retrieve the platform window.";
|
||||
|
@ -866,4 +869,20 @@ void Utilities::startSystemResize(QWindow *window, const Qt::Edges edges)
|
|||
#endif
|
||||
}
|
||||
|
||||
bool Utilities::isWindowFrameBorderVisible()
|
||||
{
|
||||
static const bool result = []() -> bool {
|
||||
// If we preserve the window frame border on systems before Windows 10,
|
||||
// the window will look rather ugly and I guess no one would like to see
|
||||
// such weired windows. If you really want to know what the window look
|
||||
// like in such situations, just comment out the following IF statement
|
||||
// and run your application on Windows 7/8/8.1.
|
||||
if (!isWin10OrGreater()) {
|
||||
return false;
|
||||
}
|
||||
return !qEnvironmentVariableIsSet("FRAMELESSHELPER_HIDE_FRAME_BORDER");
|
||||
}();
|
||||
return result;
|
||||
}
|
||||
|
||||
FRAMELESSHELPER_END_NAMESPACE
|
||||
|
|
Loading…
Reference in New Issue