Add a way to ignore title bar.

If a window is in fullscreen mode, it should not have a title bar.

Maybe a rare use case, but better than nothing.

Signed-off-by: Yuhang Zhao <2546789017@qq.com>
This commit is contained in:
Yuhang Zhao 2020-05-17 17:35:09 +08:00
parent a461c529da
commit d28e3d167c
6 changed files with 96 additions and 40 deletions

View File

@ -298,6 +298,19 @@ void FramelessHelper::setResizable(QObject *const obj, const bool val) {
}
}
bool FramelessHelper::getTitleBarEnabled(QObject *const obj) const {
if (!obj) {
return true;
}
return !m_disableTitleBar.value(obj);
}
void FramelessHelper::setTitleBarEnabled(QObject *const obj, const bool val) {
if (obj) {
m_disableTitleBar[obj] = !val;
}
}
void FramelessHelper::removeWindowFrame(QObject *const obj) {
if (obj) {
// Don't miss the Qt::Window flag.
@ -512,7 +525,8 @@ bool FramelessHelper::eventFilter(QObject *object, QEvent *event) {
return ((point.y() <= m_titleBarHeight) &&
isInDraggableAreas(point, window) &&
isInDraggableObjects(globalPoint, window) &&
isResizePermitted(globalPoint, point, window));
isResizePermitted(globalPoint, point, window) &&
getTitleBarEnabled(window));
}
return false;
};

View File

@ -77,6 +77,9 @@ public:
bool getResizable(QObject *const obj) const;
void setResizable(QObject *const obj, const bool val);
bool getTitleBarEnabled(QObject *const obj) const;
void setTitleBarEnabled(QObject *const obj, const bool val);
void removeWindowFrame(QObject *const obj);
protected:
@ -90,5 +93,5 @@ private:
QHash<QObject *, QVector<QRect>> m_ignoreAreas = {}, m_draggableAreas = {};
QHash<QObject *, QVector<QPointer<QObject>>> m_ignoreObjects = {},
m_draggableObjects = {};
QHash<QObject *, bool> m_fixedSize = {};
QHash<QObject *, bool> m_fixedSize = {}, m_disableTitleBar = {};
};

View File

@ -183,7 +183,43 @@ void FramelessQuickHelper::setResizable(const bool val) {
}
}
QSizeF FramelessQuickHelper::minimumSize() const {
bool FramelessQuickHelper::titleBarEnabled() const {
const auto win = window();
if (win) {
#ifdef Q_OS_WINDOWS
const auto hWnd = reinterpret_cast<HWND>(win->winId());
if (hWnd) {
const auto data = WinNativeEventFilter::windowData(hWnd);
if (data) {
return !data->disableTitleBar;
}
}
#else
return m_framelessHelper.getTitleBarEnabled(win);
#endif
}
return true;
}
void FramelessQuickHelper::setTitleBarEnabled(const bool val) {
const auto win = window();
if (win) {
#ifdef Q_OS_WINDOWS
const auto hWnd = reinterpret_cast<HWND>(win->winId());
if (hWnd) {
const auto data = WinNativeEventFilter::windowData(hWnd);
if (data) {
data->disableTitleBar = !val;
Q_EMIT titleBarEnabledChanged(val);
}
}
#else
m_framelessHelper.setTitleBarEnabled(win, val);
#endif
}
}
QSize FramelessQuickHelper::minimumSize() const {
const auto win = window();
if (win) {
#ifdef Q_OS_WINDOWS
@ -198,10 +234,10 @@ QSizeF FramelessQuickHelper::minimumSize() const {
return win->minimumSize();
#endif
}
return {0.0, 0.0};
return {0, 0};
}
void FramelessQuickHelper::setMinimumSize(const QSizeF &val) {
void FramelessQuickHelper::setMinimumSize(const QSize &val) {
const auto win = window();
if (win) {
#ifdef Q_OS_WINDOWS
@ -209,18 +245,18 @@ void FramelessQuickHelper::setMinimumSize(const QSizeF &val) {
if (hWnd) {
const auto data = WinNativeEventFilter::windowData(hWnd);
if (data) {
data->minimumSize = {qRound(val.width()), qRound(val.height())};
data->minimumSize = val;
Q_EMIT minimumSizeChanged(val);
}
}
#else
win->setMinimumSize({qRound(val.width()), qRound(val.height())});
win->setMinimumSize(val);
Q_EMIT minimumSizeChanged(val);
#endif
}
}
QSizeF FramelessQuickHelper::maximumSize() const {
QSize FramelessQuickHelper::maximumSize() const {
const auto win = window();
if (win) {
#ifdef Q_OS_WINDOWS
@ -235,10 +271,10 @@ QSizeF FramelessQuickHelper::maximumSize() const {
return win->maximumSize();
#endif
}
return {0.0, 0.0};
return {0, 0};
}
void FramelessQuickHelper::setMaximumSize(const QSizeF &val) {
void FramelessQuickHelper::setMaximumSize(const QSize &val) {
const auto win = window();
if (win) {
#ifdef Q_OS_WINDOWS
@ -246,12 +282,12 @@ void FramelessQuickHelper::setMaximumSize(const QSizeF &val) {
if (hWnd) {
const auto data = WinNativeEventFilter::windowData(hWnd);
if (data) {
data->maximumSize = {qRound(val.width()), qRound(val.height())};
data->maximumSize = val;
Q_EMIT maximumSizeChanged(val);
}
}
#else
win->setMaximumSize({qRound(val.width()), qRound(val.height())});
win->setMaximumSize(val);
Q_EMIT maximumSizeChanged(val);
#endif
}

View File

@ -57,10 +57,12 @@ class FramelessQuickHelper : public QQuickItem {
NOTIFY titleBarHeightChanged)
Q_PROPERTY(bool resizable READ resizable WRITE setResizable NOTIFY
resizableChanged)
Q_PROPERTY(QSizeF minimumSize READ minimumSize WRITE setMinimumSize NOTIFY
Q_PROPERTY(QSize minimumSize READ minimumSize WRITE setMinimumSize NOTIFY
minimumSizeChanged)
Q_PROPERTY(QSizeF maximumSize READ maximumSize WRITE setMaximumSize NOTIFY
Q_PROPERTY(QSize maximumSize READ maximumSize WRITE setMaximumSize NOTIFY
maximumSizeChanged)
Q_PROPERTY(bool titleBarEnabled READ titleBarEnabled WRITE
setTitleBarEnabled NOTIFY titleBarEnabledChanged)
public:
explicit FramelessQuickHelper(QQuickItem *parent = nullptr);
@ -78,11 +80,14 @@ public:
bool resizable() const;
void setResizable(const bool val);
QSizeF minimumSize() const;
void setMinimumSize(const QSizeF &val);
QSize minimumSize() const;
void setMinimumSize(const QSize &val);
QSizeF maximumSize() const;
void setMaximumSize(const QSizeF &val);
QSize maximumSize() const;
void setMaximumSize(const QSize &val);
bool titleBarEnabled() const;
void setTitleBarEnabled(const bool val);
public Q_SLOTS:
void removeWindowFrame(const bool center = true);
@ -109,8 +114,9 @@ Q_SIGNALS:
void borderHeightChanged(int);
void titleBarHeightChanged(int);
void resizableChanged(bool);
void minimumSizeChanged(const QSizeF &);
void maximumSizeChanged(const QSizeF &);
void minimumSizeChanged(const QSize &);
void maximumSizeChanged(const QSize &);
void titleBarEnabledChanged(bool);
private:
#ifndef Q_OS_WINDOWS

View File

@ -1345,7 +1345,7 @@ bool WinNativeEventFilter::nativeEventFilter(const QByteArray &eventType,
return true;
}
const auto getHTResult = [](const HWND _hWnd, const LPARAM _lParam,
const WINDOW *_data) -> LRESULT {
const WINDOWDATA &_data) -> LRESULT {
const auto isInSpecificAreas = [](const int x, const int y,
const QVector<QRect> &areas,
const qreal dpr) -> bool {
@ -1424,23 +1424,20 @@ bool WinNativeEventFilter::nativeEventFilter(const QByteArray &eventType,
const LONG tbh =
getSystemMetric(_hWnd, SystemMetric::TitleBarHeight);
const qreal dpr = GetDevicePixelRatioForWindow(_hWnd);
const bool isInIgnoreAreas = isInSpecificAreas(
mouse.x, mouse.y, _data->windowData.ignoreAreas, dpr);
const bool isInDraggableAreas =
_data->windowData.draggableAreas.isEmpty()
const bool isInIgnoreAreas =
isInSpecificAreas(mouse.x, mouse.y, _data.ignoreAreas, dpr);
const bool isInDraggableAreas = _data.draggableAreas.isEmpty()
? true
: isInSpecificAreas(mouse.x, mouse.y,
_data->windowData.draggableAreas, dpr);
: isInSpecificAreas(mouse.x, mouse.y, _data.draggableAreas,
dpr);
#if defined(QT_WIDGETS_LIB) || defined(QT_QUICK_LIB)
const bool isInIgnoreObjects =
isInSpecificObjects(globalMouse.x, globalMouse.y,
_data->windowData.ignoreObjects, dpr);
const bool isInIgnoreObjects = isInSpecificObjects(
globalMouse.x, globalMouse.y, _data.ignoreObjects, dpr);
const bool isInDraggableObjects =
_data->windowData.draggableObjects.isEmpty()
_data.draggableObjects.isEmpty()
? true
: isInSpecificObjects(globalMouse.x, globalMouse.y,
_data->windowData.draggableObjects,
dpr);
_data.draggableObjects, dpr);
#else
// Don't block resizing if both of the Qt Widgets module and Qt
// Quick module are not compiled in, although there's not much
@ -1450,11 +1447,11 @@ bool WinNativeEventFilter::nativeEventFilter(const QByteArray &eventType,
#endif
const bool isResizePermitted =
!isInIgnoreAreas && !isInIgnoreObjects;
const bool isTitlebar = (mouse.y <= tbh) &&
const bool isTitleBar = (mouse.y <= tbh) &&
isInDraggableAreas && isInDraggableObjects &&
isResizePermitted;
isResizePermitted && !_data.disableTitleBar;
if (IsMaximized(_hWnd)) {
if (isTitlebar) {
if (isTitleBar) {
return HTCAPTION;
}
return HTCLIENT;
@ -1466,7 +1463,7 @@ bool WinNativeEventFilter::nativeEventFilter(const QByteArray &eventType,
const int factor = (isTop || isBottom) ? 2 : 1;
const bool isLeft = (mouse.x <= (bw * factor));
const bool isRight = (mouse.x >= (ww - (bw * factor)));
const bool fixedSize = _data->windowData.fixedSize;
const bool fixedSize = _data.fixedSize;
const auto getBorderValue = [fixedSize](int value) -> int {
// HTBORDER: non-resizeable window border.
return fixedSize ? HTBORDER : value;
@ -1495,12 +1492,12 @@ bool WinNativeEventFilter::nativeEventFilter(const QByteArray &eventType,
if (isRight) {
return getBorderValue(HTRIGHT);
}
if (isTitlebar) {
if (isTitleBar) {
return HTCAPTION;
}
return HTCLIENT;
};
*result = getHTResult(msg->hwnd, msg->lParam, data);
*result = getHTResult(msg->hwnd, msg->lParam, data->windowData);
return true;
}
case WM_GETMINMAXINFO: {

View File

@ -55,7 +55,7 @@ public:
using WINDOWDATA = struct _WINDOWDATA {
BOOL fixedSize = FALSE, mouseTransparent = FALSE,
restoreDefaultWindowStyles = FALSE,
doNotEnableLayeredWindow = FALSE;
doNotEnableLayeredWindow = FALSE, disableTitleBar = FALSE;
int borderWidth = -1, borderHeight = -1, titleBarHeight = -1;
QVector<QRect> ignoreAreas = {}, draggableAreas = {};
QVector<QPointer<QObject>> ignoreObjects = {}, draggableObjects = {};