Skip to content
This repository has been archived by the owner on Dec 19, 2023. It is now read-only.

Commit

Permalink
general improvements
Browse files Browse the repository at this point in the history
1. replace raw char array with QByteArray
2. Register QWindow for Quick module
3. Account for hidden and disable state when hovering controls
4. fix quick title bar label alignment

Signed-off-by: Yuhang Zhao <[email protected]>
  • Loading branch information
wangwenx190 committed Jun 1, 2022
1 parent 0cff5ff commit a04fd53
Show file tree
Hide file tree
Showing 7 changed files with 98 additions and 48 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ class FRAMELESSHELPER_QUICK_API FramelessQuickHelperPrivate : public QObject
Q_NODISCARD bool isWindowFixedSize() const;
void setWindowFixedSize(const bool value);

void emitSignalForAllInstances(const char *signal);
void emitSignalForAllInstances(const QByteArray &signal);

private:
Q_NODISCARD QRect mapItemGeometryToScene(const QQuickItem * const item) const;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ class FRAMELESSHELPER_WIDGETS_API FramelessWidgetsHelperPrivate : public QObject
Q_NODISCARD bool isWindowFixedSize() const;
void setWindowFixedSize(const bool value);

void emitSignalForAllInstances(const char *signal);
void emitSignalForAllInstances(const QByteArray &signal);

private:
Q_NODISCARD QRect mapWidgetGeometryToScene(const QWidget * const widget) const;
Expand Down
29 changes: 18 additions & 11 deletions src/core/framelessconfig.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,17 +34,23 @@ using namespace Global;

FRAMELESSHELPER_STRING_CONSTANT2(ConfigFileName, ".framelesshelper.ini")

static constexpr const struct
static const struct
{
const char *env = nullptr;
const char *ini = nullptr;
const QByteArray env = {};
const QByteArray cfg = {};
} OptionsTable[] = {
{"FRAMELESSHELPER_USE_CROSS_PLATFORM_QT_IMPLEMENTATION", "Options/UseCrossPlatformQtImplementation"},
{"FRAMELESSHELPER_FORCE_HIDE_WINDOW_FRAME_BORDER", "Options/ForceHideWindowFrameBorder"},
{"FRAMELESSHELPER_FORCE_SHOW_WINDOW_FRAME_BORDER", "Options/ForceShowWindowFrameBorder"},
{"FRAMELESSHELPER_DISABLE_WINDOWS_SNAP_LAYOUTS", "Options/DisableWindowsSnapLayouts"},
{"FRAMELESSHELPER_WINDOW_USE_ROUND_CORNERS", "Options/WindowUseRoundCorners"},
{"FRAMELESSHELPER_CENTER_WINDOW_BEFORE_SHOW", "Options/CenterWindowBeforeShow"}
{FRAMELESSHELPER_BYTEARRAY_LITERAL("FRAMELESSHELPER_USE_CROSS_PLATFORM_QT_IMPLEMENTATION"),
FRAMELESSHELPER_BYTEARRAY_LITERAL("Options/UseCrossPlatformQtImplementation")},
{FRAMELESSHELPER_BYTEARRAY_LITERAL("FRAMELESSHELPER_FORCE_HIDE_WINDOW_FRAME_BORDER"),
FRAMELESSHELPER_BYTEARRAY_LITERAL("Options/ForceHideWindowFrameBorder")},
{FRAMELESSHELPER_BYTEARRAY_LITERAL("FRAMELESSHELPER_FORCE_SHOW_WINDOW_FRAME_BORDER"),
FRAMELESSHELPER_BYTEARRAY_LITERAL("Options/ForceShowWindowFrameBorder")},
{FRAMELESSHELPER_BYTEARRAY_LITERAL("FRAMELESSHELPER_DISABLE_WINDOWS_SNAP_LAYOUTS"),
FRAMELESSHELPER_BYTEARRAY_LITERAL("Options/DisableWindowsSnapLayouts")},
{FRAMELESSHELPER_BYTEARRAY_LITERAL("FRAMELESSHELPER_WINDOW_USE_ROUND_CORNERS"),
FRAMELESSHELPER_BYTEARRAY_LITERAL("Options/WindowUseRoundCorners")},
{FRAMELESSHELPER_BYTEARRAY_LITERAL("FRAMELESSHELPER_CENTER_WINDOW_BEFORE_SHOW"),
FRAMELESSHELPER_BYTEARRAY_LITERAL("Options/CenterWindowBeforeShow")}
};

static constexpr const auto OptionCount = std::size(OptionsTable);
Expand Down Expand Up @@ -86,8 +92,9 @@ void FramelessConfig::reload(const bool force)
return new QSettings(appDir.filePath(kConfigFileName), QSettings::IniFormat);
}());
for (int i = 0; i != OptionCount; ++i) {
const bool on = (qEnvironmentVariableIsSet(OptionsTable[i].env) && (qEnvironmentVariableIntValue(OptionsTable[i].env) > 0))
|| (!configFile.isNull() && configFile->value(QUtf8String(OptionsTable[i].ini), false).toBool());
const bool on = (qEnvironmentVariableIsSet(OptionsTable[i].env.constData())
&& (qEnvironmentVariableIntValue(OptionsTable[i].env.constData()) > 0))
|| (!configFile.isNull() && configFile->value(QUtf8String(OptionsTable[i].cfg), false).toBool());
g_data()->options[i] = on;
}
g_data()->loaded = true;
Expand Down
50 changes: 34 additions & 16 deletions src/quick/framelessquickhelper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ void FramelessQuickHelperPrivate::setTitleBarItem(QQuickItem *value)
return;
}
data->titleBarItem = value;
emitSignalForAllInstances("titleBarItemChanged");
emitSignalForAllInstances(FRAMELESSHELPER_BYTEARRAY_LITERAL("titleBarItemChanged"));
}

void FramelessQuickHelperPrivate::attachToWindow()
Expand Down Expand Up @@ -184,7 +184,7 @@ void FramelessQuickHelperPrivate::attachToWindow()
if (FramelessConfig::instance()->isSet(Option::CenterWindowBeforeShow)) {
moveWindowToDesktopCenter();
}
emitSignalForAllInstances("ready");
emitSignalForAllInstances(FRAMELESSHELPER_BYTEARRAY_LITERAL("ready"));
});
}

Expand Down Expand Up @@ -305,7 +305,7 @@ void FramelessQuickHelperPrivate::bringWindowToFront()
window->show();
}
if (window->visibility() == QQuickWindow::Minimized) {
window->showNormal(); // ### FIXME
window->showNormal(); // ### FIXME: we should not show normal, we should restore the previous state.
}
window->raise();
window->requestActivate();
Expand Down Expand Up @@ -353,10 +353,10 @@ void FramelessQuickHelperPrivate::setWindowFixedSize(const bool value)
Q_EMIT q->windowFixedSizeChanged();
}

void FramelessQuickHelperPrivate::emitSignalForAllInstances(const char *signal)
void FramelessQuickHelperPrivate::emitSignalForAllInstances(const QByteArray &signal)
{
Q_ASSERT(signal);
if (!signal) {
Q_ASSERT(!signal.isEmpty());
if (signal.isEmpty()) {
return;
}
Q_Q(FramelessQuickHelper);
Expand All @@ -370,7 +370,7 @@ void FramelessQuickHelperPrivate::emitSignalForAllInstances(const char *signal)
return;
}
for (auto &&instance : qAsConst(instances)) {
QMetaObject::invokeMethod(instance, signal);
QMetaObject::invokeMethod(instance, signal.constData());
}
}

Expand All @@ -397,31 +397,31 @@ bool FramelessQuickHelperPrivate::isInSystemButtons(const QPoint &pos, QuickGlob
}
*button = QuickGlobal::SystemButtonType::Unknown;
const QuickHelperData data = getWindowData();
if (data.windowIconButton) {
if (data.windowIconButton && data.windowIconButton->isVisible() && data.windowIconButton->isEnabled()) {
if (mapItemGeometryToScene(data.windowIconButton).contains(pos)) {
*button = QuickGlobal::SystemButtonType::WindowIcon;
return true;
}
}
if (data.contextHelpButton) {
if (data.contextHelpButton && data.contextHelpButton->isVisible() && data.contextHelpButton->isEnabled()) {
if (mapItemGeometryToScene(data.contextHelpButton).contains(pos)) {
*button = QuickGlobal::SystemButtonType::Help;
return true;
}
}
if (data.minimizeButton) {
if (data.minimizeButton && data.minimizeButton->isVisible() && data.minimizeButton->isEnabled()) {
if (mapItemGeometryToScene(data.minimizeButton).contains(pos)) {
*button = QuickGlobal::SystemButtonType::Minimize;
return true;
}
}
if (data.maximizeButton) {
if (data.maximizeButton && data.maximizeButton->isVisible() && data.maximizeButton->isEnabled()) {
if (mapItemGeometryToScene(data.maximizeButton).contains(pos)) {
*button = QuickGlobal::SystemButtonType::Maximize;
return true;
}
}
if (data.closeButton) {
if (data.closeButton && data.closeButton->isVisible() && data.closeButton->isEnabled()) {
if (mapItemGeometryToScene(data.closeButton).contains(pos)) {
*button = QuickGlobal::SystemButtonType::Close;
return true;
Expand All @@ -434,20 +434,38 @@ bool FramelessQuickHelperPrivate::isInTitleBarDraggableArea(const QPoint &pos) c
{
const QuickHelperData data = getWindowData();
if (!data.titleBarItem) {
// There's no title bar at all, the mouse will always be in the client area.
return false;
}
QRegion region = mapItemGeometryToScene(data.titleBarItem);
if (!data.titleBarItem->isVisible() || !data.titleBarItem->isEnabled()) {
// The title bar is hidden or disabled for some reason, treat it as there's no title bar.
return false;
}
Q_Q(const FramelessQuickHelper);
const QQuickWindow * const window = q->window();
if (!window) {
// The FramelessQuickHelper item has not been attached to a specific window yet,
// so we assume there's no title bar.
return false;
}
const QRect windowRect = {QPoint(0, 0), window->size()};
const QRect titleBarRect = mapItemGeometryToScene(data.titleBarItem);
if (!titleBarRect.intersects(windowRect)) {
// The title bar is totally outside of the window for some reason,
// also treat it as there's no title bar.
return false;
}
QRegion region = titleBarRect;
const auto systemButtons = {data.windowIconButton, data.contextHelpButton,
data.minimizeButton, data.maximizeButton, data.closeButton};
for (auto &&button : qAsConst(systemButtons)) {
if (button) {
if (button && button->isVisible() && button->isEnabled()) {
region -= mapItemGeometryToScene(button);
}
}
if (!data.hitTestVisibleItems.isEmpty()) {
for (auto &&item : qAsConst(data.hitTestVisibleItems)) {
Q_ASSERT(item);
if (item) {
if (item && item->isVisible() && item->isEnabled()) {
region -= mapItemGeometryToScene(item);
}
}
Expand Down
1 change: 1 addition & 0 deletions src/quick/framelessquickmodule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ void FramelessHelper::Quick::registerTypes(QQmlEngine *engine)
Q_UNUSED(scriptEngine);
return new FramelessQuickUtils;
});
qmlRegisterRevision<QWindow, 254>(QUICK_URI_FULL);
qmlRegisterRevision<QQuickWindow, 254>(QUICK_URI_FULL);
qmlRegisterRevision<QQuickItem, 254>(QUICK_URI_FULL);
qmlRegisterType<FramelessQuickHelper>(QUICK_URI_EXPAND("FramelessHelper"));
Expand Down
15 changes: 11 additions & 4 deletions src/quick/quickstandardtitlebar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,13 @@ void QuickStandardTitleBar::setTitleLabelAlignment(const Qt::Alignment value)
}
m_labelAlignment = value;
QQuickAnchors * const labelAnchors = QQuickItemPrivate::get(m_windowTitleLabel.data())->anchors();
//labelAnchors->setMargins(0);
labelAnchors->resetFill();
labelAnchors->resetCenterIn();
labelAnchors->resetTop();
labelAnchors->resetBottom();
labelAnchors->resetLeft();
labelAnchors->resetRight();
const QQuickItemPrivate * const titleBarPriv = QQuickItemPrivate::get(this);
if (m_labelAlignment & Qt::AlignTop) {
labelAnchors->setTop(titleBarPriv->top());
Expand All @@ -75,13 +82,13 @@ void QuickStandardTitleBar::setTitleLabelAlignment(const Qt::Alignment value)
labelAnchors->setRightMargin(kDefaultTitleBarContentsMargin);
}
if (m_labelAlignment & Qt::AlignVCenter) {
labelAnchors->setTopMargin(0);
labelAnchors->setBottomMargin(0);
//labelAnchors->setTopMargin(0);
//labelAnchors->setBottomMargin(0);
labelAnchors->setVerticalCenter(titleBarPriv->verticalCenter());
}
if (m_labelAlignment & Qt::AlignHCenter) {
labelAnchors->setLeftMargin(0);
labelAnchors->setRightMargin(0);
//labelAnchors->setLeftMargin(0);
//labelAnchors->setRightMargin(0);
labelAnchors->setHorizontalCenter(titleBarPriv->horizontalCenter());
}
Q_EMIT titleLabelAlignmentChanged();
Expand Down
47 changes: 32 additions & 15 deletions src/widgets/framelesswidgetshelper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -130,10 +130,10 @@ void FramelessWidgetsHelperPrivate::setWindowFixedSize(const bool value)
Q_EMIT q->windowFixedSizeChanged();
}

void FramelessWidgetsHelperPrivate::emitSignalForAllInstances(const char *signal)
void FramelessWidgetsHelperPrivate::emitSignalForAllInstances(const QByteArray &signal)
{
Q_ASSERT(signal);
if (!signal) {
Q_ASSERT(!signal.isEmpty());
if (signal.isEmpty()) {
return;
}
const QWidget * const window = getWindow();
Expand All @@ -145,7 +145,7 @@ void FramelessWidgetsHelperPrivate::emitSignalForAllInstances(const char *signal
return;
}
for (auto &&instance : qAsConst(instances)) {
QMetaObject::invokeMethod(instance, signal);
QMetaObject::invokeMethod(instance, signal.constData());
}
}

Expand All @@ -164,7 +164,7 @@ void FramelessWidgetsHelperPrivate::setTitleBarWidget(QWidget *widget)
return;
}
data->titleBarWidget = widget;
emitSignalForAllInstances("titleBarWidgetChanged");
emitSignalForAllInstances(FRAMELESSHELPER_BYTEARRAY_LITERAL("titleBarWidgetChanged"));
}

QWidget *FramelessWidgetsHelperPrivate::getTitleBarWidget() const
Expand Down Expand Up @@ -268,7 +268,7 @@ void FramelessWidgetsHelperPrivate::attachToWindow()
if (FramelessConfig::instance()->isSet(Option::CenterWindowBeforeShow)) {
moveWindowToDesktopCenter();
}
emitSignalForAllInstances("ready");
emitSignalForAllInstances(FRAMELESSHELPER_BYTEARRAY_LITERAL("ready"));
});
}

Expand Down Expand Up @@ -338,31 +338,31 @@ bool FramelessWidgetsHelperPrivate::isInSystemButtons(const QPoint &pos, SystemB
}
*button = SystemButtonType::Unknown;
const WidgetsHelperData data = getWindowData();
if (data.windowIconButton) {
if (data.windowIconButton && data.windowIconButton->isVisible() && data.windowIconButton->isEnabled()) {
if (data.windowIconButton->geometry().contains(pos)) {
*button = SystemButtonType::WindowIcon;
return true;
}
}
if (data.contextHelpButton) {
if (data.contextHelpButton && data.contextHelpButton->isVisible() && data.contextHelpButton->isEnabled()) {
if (data.contextHelpButton->geometry().contains(pos)) {
*button = SystemButtonType::Help;
return true;
}
}
if (data.minimizeButton) {
if (data.minimizeButton && data.minimizeButton->isVisible() && data.minimizeButton->isEnabled()) {
if (data.minimizeButton->geometry().contains(pos)) {
*button = SystemButtonType::Minimize;
return true;
}
}
if (data.maximizeButton) {
if (data.maximizeButton && data.maximizeButton->isVisible() && data.maximizeButton->isEnabled()) {
if (data.maximizeButton->geometry().contains(pos)) {
*button = SystemButtonType::Maximize;
return true;
}
}
if (data.closeButton) {
if (data.closeButton && data.closeButton->isVisible() && data.closeButton->isEnabled()) {
if (data.closeButton->geometry().contains(pos)) {
*button = SystemButtonType::Close;
return true;
Expand All @@ -375,20 +375,37 @@ bool FramelessWidgetsHelperPrivate::isInTitleBarDraggableArea(const QPoint &pos)
{
const WidgetsHelperData data = getWindowData();
if (!data.titleBarWidget) {
// There's no title bar at all, the mouse will always be in the client area.
return false;
}
QRegion region = mapWidgetGeometryToScene(data.titleBarWidget);
if (!data.titleBarWidget->isVisible() || !data.titleBarWidget->isEnabled()) {
// The title bar is hidden or disabled for some reason, treat it as there's no title bar.
return false;
}
const QWidget * const window = getWindow();
if (!window) {
// The FramelessWidgetsHelper object has not been attached to a specific window yet,
// so we assume there's no title bar.
return false;
}
const QRect windowRect = {QPoint(0, 0), window->size()};
const QRect titleBarRect = mapWidgetGeometryToScene(data.titleBarWidget);
if (!titleBarRect.intersects(windowRect)) {
// The title bar is totally outside of the window for some reason,
// also treat it as there's no title bar.
return false;
}
QRegion region = titleBarRect;
const auto systemButtons = {data.windowIconButton, data.contextHelpButton,
data.minimizeButton, data.maximizeButton, data.closeButton};
for (auto &&button : qAsConst(systemButtons)) {
if (button) {
if (button && button->isVisible() && button->isEnabled()) {
region -= mapWidgetGeometryToScene(button);
}
}
if (!data.hitTestVisibleWidgets.isEmpty()) {
for (auto &&widget : qAsConst(data.hitTestVisibleWidgets)) {
Q_ASSERT(widget);
if (widget) {
if (widget && widget->isVisible() && widget->isEnabled()) {
region -= mapWidgetGeometryToScene(widget);
}
}
Expand Down

0 comments on commit a04fd53

Please sign in to comment.