general improvements
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 <2546789017@qq.com>
This commit is contained in:
parent
0cff5ff48e
commit
a04fd53a38
|
@ -65,7 +65,7 @@ public:
|
|||
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;
|
||||
|
|
|
@ -61,7 +61,7 @@ public:
|
|||
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;
|
||||
|
|
|
@ -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);
|
||||
|
@ -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;
|
||||
|
|
|
@ -111,7 +111,7 @@ void FramelessQuickHelperPrivate::setTitleBarItem(QQuickItem *value)
|
|||
return;
|
||||
}
|
||||
data->titleBarItem = value;
|
||||
emitSignalForAllInstances("titleBarItemChanged");
|
||||
emitSignalForAllInstances(FRAMELESSHELPER_BYTEARRAY_LITERAL("titleBarItemChanged"));
|
||||
}
|
||||
|
||||
void FramelessQuickHelperPrivate::attachToWindow()
|
||||
|
@ -184,7 +184,7 @@ void FramelessQuickHelperPrivate::attachToWindow()
|
|||
if (FramelessConfig::instance()->isSet(Option::CenterWindowBeforeShow)) {
|
||||
moveWindowToDesktopCenter();
|
||||
}
|
||||
emitSignalForAllInstances("ready");
|
||||
emitSignalForAllInstances(FRAMELESSHELPER_BYTEARRAY_LITERAL("ready"));
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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"));
|
||||
|
|
|
@ -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());
|
||||
|
@ -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();
|
||||
|
|
|
@ -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();
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -164,7 +164,7 @@ void FramelessWidgetsHelperPrivate::setTitleBarWidget(QWidget *widget)
|
|||
return;
|
||||
}
|
||||
data->titleBarWidget = widget;
|
||||
emitSignalForAllInstances("titleBarWidgetChanged");
|
||||
emitSignalForAllInstances(FRAMELESSHELPER_BYTEARRAY_LITERAL("titleBarWidgetChanged"));
|
||||
}
|
||||
|
||||
QWidget *FramelessWidgetsHelperPrivate::getTitleBarWidget() const
|
||||
|
@ -268,7 +268,7 @@ void FramelessWidgetsHelperPrivate::attachToWindow()
|
|||
if (FramelessConfig::instance()->isSet(Option::CenterWindowBeforeShow)) {
|
||||
moveWindowToDesktopCenter();
|
||||
}
|
||||
emitSignalForAllInstances("ready");
|
||||
emitSignalForAllInstances(FRAMELESSHELPER_BYTEARRAY_LITERAL("ready"));
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue