Signed-off-by: Yuhang Zhao <2546789017@qq.com>
This commit is contained in:
Yuhang Zhao 2020-04-05 17:21:18 +08:00
parent 38c4d465b2
commit df6b381006
1 changed files with 56 additions and 25 deletions

View File

@ -52,6 +52,8 @@ FramelessHelper::FramelessHelper(QObject *parent) : QObject(parent) {
m_borderHeight = WinNativeEventFilter::borderHeight(nullptr); m_borderHeight = WinNativeEventFilter::borderHeight(nullptr);
m_titlebarHeight = WinNativeEventFilter::titlebarHeight(nullptr); m_titlebarHeight = WinNativeEventFilter::titlebarHeight(nullptr);
#else #else
// TODO: The default border width and height on Windows is 8 pixels if DPI
// is 96. Don't know how to acquire these values on UNIX platforms.
m_borderWidth = 8; m_borderWidth = 8;
m_borderHeight = 8; m_borderHeight = 8;
QWidget widget; QWidget widget;
@ -203,9 +205,17 @@ void FramelessHelper::setFramelessWindows(const QVector<QObject *> &val) {
#ifndef Q_OS_WINDOWS #ifndef Q_OS_WINDOWS
bool FramelessHelper::eventFilter(QObject *object, QEvent *event) { bool FramelessHelper::eventFilter(QObject *object, QEvent *event) {
// TODO: Judge whether it's a top level window and whether we should filter const auto isWindowTopLevel = [](QObject *window) -> bool {
// it. if (window) {
if (!object) { if (window->isWidgetType()) {
return qobject_cast<QWidget *>(window)->isTopLevel();
} else if (window->isWindowType()) {
return qobject_cast<QWindow *>(window)->isTopLevel();
}
}
return false;
};
if (!object || !isWindowTopLevel(object)) {
event->ignore(); event->ignore();
return false; return false;
} }
@ -283,8 +293,8 @@ bool FramelessHelper::eventFilter(QObject *object, QEvent *event) {
} }
return false; return false;
}; };
const auto moveOrResize = [this, object, &getWindowEdges, const auto moveOrResize = [this, &getWindowEdges, &isInTitlebarArea](
&isInTitlebarArea](const QPointF &point) { const QPointF &point, QObject *object) {
QWindow *window = getWindowHandle(object); QWindow *window = getWindowHandle(object);
if (window) { if (window) {
const Qt::Edges edges = const Qt::Edges edges =
@ -294,7 +304,10 @@ bool FramelessHelper::eventFilter(QObject *object, QEvent *event) {
window->startSystemMove(); window->startSystemMove();
} }
} else { } else {
window->startSystemResize(edges); if (window->windowStates().testFlag(
Qt::WindowState::WindowNoState)) {
window->startSystemResize(edges);
}
} }
} else { } else {
qWarning().noquote() << "Can't move or resize the window: failed " qWarning().noquote() << "Can't move or resize the window: failed "
@ -309,18 +322,29 @@ bool FramelessHelper::eventFilter(QObject *object, QEvent *event) {
break; break;
} }
if (isInTitlebarArea(mouseEvent->localPos(), object)) { if (isInTitlebarArea(mouseEvent->localPos(), object)) {
QWindow *window = getWindowHandle(object); // FIXME: If the current object is a QWidget, we can use
if (window) { // getWindowHandle(object) to get the window handle, but if we
if (window->windowStates().testFlag(Qt::WindowFullScreen)) { // call showMaximized() of that window, it will not be
break; // maximized, it will be moved to the top-left edge of the
// screen without changing it's size instead. Why? Convert the
// object to QWidget and call showMaximized() doesn't have this
// issue.
if (object->isWindowType()) {
const auto window = qobject_cast<QWindow *>(object);
if (window) {
if (window->windowStates().testFlag(
Qt::WindowState::WindowFullScreen)) {
break;
}
if (window->windowStates().testFlag(
Qt::WindowState::WindowMaximized)) {
window->showNormal();
} else {
window->showMaximized();
}
window->setCursor(Qt::CursorShape::ArrowCursor);
} }
if (window->windowStates().testFlag(Qt::WindowMaximized)) { } else if (object->isWidgetType()) {
window->showNormal();
} else {
window->showMaximized();
}
window->setCursor(Qt::CursorShape::ArrowCursor);
} else {
const auto widget = qobject_cast<QWidget *>(object); const auto widget = qobject_cast<QWidget *>(object);
if (widget) { if (widget) {
if (widget->isFullScreen()) { if (widget->isFullScreen()) {
@ -344,7 +368,7 @@ bool FramelessHelper::eventFilter(QObject *object, QEvent *event) {
if (mouseEvent->button() != Qt::MouseButton::LeftButton) { if (mouseEvent->button() != Qt::MouseButton::LeftButton) {
break; break;
} }
moveOrResize(mouseEvent->localPos()); moveOrResize(mouseEvent->localPos(), object);
} }
break; break;
} }
@ -353,15 +377,21 @@ bool FramelessHelper::eventFilter(QObject *object, QEvent *event) {
if (mouseEvent) { if (mouseEvent) {
QWindow *window = getWindowHandle(object); QWindow *window = getWindowHandle(object);
if (window) { if (window) {
window->setCursor(getCursorShape( if (window->windowStates().testFlag(
getWindowEdges(mouseEvent->localPos(), window->width(), Qt::WindowState::WindowNoState)) {
window->height()))); window->setCursor(getCursorShape(
getWindowEdges(mouseEvent->localPos(), window->width(),
window->height())));
}
} else { } else {
const auto widget = qobject_cast<QWidget *>(object); const auto widget = qobject_cast<QWidget *>(object);
if (widget) { if (widget) {
widget->setCursor(getCursorShape( if (!widget->isMinimized() && !widget->isMaximized() &&
getWindowEdges(mouseEvent->localPos(), widget->width(), !widget->isFullScreen()) {
widget->height()))); widget->setCursor(getCursorShape(
getWindowEdges(mouseEvent->localPos(),
widget->width(), widget->height())));
}
} }
} }
} }
@ -370,7 +400,8 @@ bool FramelessHelper::eventFilter(QObject *object, QEvent *event) {
case QEvent::TouchBegin: case QEvent::TouchBegin:
case QEvent::TouchUpdate: { case QEvent::TouchUpdate: {
moveOrResize( moveOrResize(
static_cast<QTouchEvent *>(event)->touchPoints().first().pos()); static_cast<QTouchEvent *>(event)->touchPoints().first().pos(),
object);
break; break;
} }
default: { default: {