forked from github_mirror/framelesshelper
various fixes and improvements
1. Make all demo applications be able to record and restore the previous window geometry. 2. Improve the robustness of the widgets and quick implementation. Signed-off-by: Yuhang Zhao <2546789017@qq.com>
This commit is contained in:
parent
915e775d94
commit
8042a78b8f
|
@ -23,13 +23,10 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <QtWidgets/qapplication.h>
|
#include <QtWidgets/qapplication.h>
|
||||||
#include <framelessconfig_p.h>
|
|
||||||
#include "mainwindow.h"
|
#include "mainwindow.h"
|
||||||
|
|
||||||
FRAMELESSHELPER_USE_NAMESPACE
|
FRAMELESSHELPER_USE_NAMESPACE
|
||||||
|
|
||||||
using namespace Global;
|
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
// Not necessary, but better call this function, before the construction
|
// Not necessary, but better call this function, before the construction
|
||||||
|
@ -38,8 +35,6 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
QApplication application(argc, argv);
|
QApplication application(argc, argv);
|
||||||
|
|
||||||
FramelessConfig::instance()->set(Option::CenterWindowBeforeShow);
|
|
||||||
|
|
||||||
MainWindow mainWindow;
|
MainWindow mainWindow;
|
||||||
mainWindow.show();
|
mainWindow.show();
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,10 @@
|
||||||
|
|
||||||
#include "mainwindow.h"
|
#include "mainwindow.h"
|
||||||
#include "ui_mainwindow.h"
|
#include "ui_mainwindow.h"
|
||||||
|
#include <QtCore/qsettings.h>
|
||||||
|
#include <QtCore/qcoreapplication.h>
|
||||||
|
#include <QtCore/qfileinfo.h>
|
||||||
|
#include <QtCore/qdir.h>
|
||||||
#include <QtWidgets/qboxlayout.h>
|
#include <QtWidgets/qboxlayout.h>
|
||||||
#include <Utils>
|
#include <Utils>
|
||||||
#include <StandardTitleBar>
|
#include <StandardTitleBar>
|
||||||
|
@ -34,6 +38,18 @@ FRAMELESSHELPER_USE_NAMESPACE
|
||||||
|
|
||||||
using namespace Global;
|
using namespace Global;
|
||||||
|
|
||||||
|
FRAMELESSHELPER_STRING_CONSTANT2(GeoKeyPath, "Window/Geometry")
|
||||||
|
FRAMELESSHELPER_STRING_CONSTANT2(StateKeyPath, "Window/State")
|
||||||
|
|
||||||
|
[[nodiscard]] static inline QSettings *appConfigFile()
|
||||||
|
{
|
||||||
|
const QFileInfo fileInfo(QCoreApplication::applicationFilePath());
|
||||||
|
const QString iniFileName = fileInfo.completeBaseName() + FRAMELESSHELPER_STRING_LITERAL(".ini");
|
||||||
|
const QString iniFilePath = fileInfo.canonicalPath() + QDir::separator() + iniFileName;
|
||||||
|
const auto settings = new QSettings(iniFilePath, QSettings::IniFormat);
|
||||||
|
return settings;
|
||||||
|
}
|
||||||
|
|
||||||
MainWindow::MainWindow(QWidget *parent, const Qt::WindowFlags flags) : FramelessMainWindow(parent, flags)
|
MainWindow::MainWindow(QWidget *parent, const Qt::WindowFlags flags) : FramelessMainWindow(parent, flags)
|
||||||
{
|
{
|
||||||
initialize();
|
initialize();
|
||||||
|
@ -41,6 +57,14 @@ MainWindow::MainWindow(QWidget *parent, const Qt::WindowFlags flags) : Frameless
|
||||||
|
|
||||||
MainWindow::~MainWindow() = default;
|
MainWindow::~MainWindow() = default;
|
||||||
|
|
||||||
|
void MainWindow::closeEvent(QCloseEvent *event)
|
||||||
|
{
|
||||||
|
const QScopedPointer<QSettings> settings(appConfigFile());
|
||||||
|
settings->setValue(kGeoKeyPath, saveGeometry());
|
||||||
|
settings->setValue(kStateKeyPath, saveState());
|
||||||
|
FramelessMainWindow::closeEvent(event);
|
||||||
|
}
|
||||||
|
|
||||||
void MainWindow::initialize()
|
void MainWindow::initialize()
|
||||||
{
|
{
|
||||||
m_titleBar.reset(new StandardTitleBar(this));
|
m_titleBar.reset(new StandardTitleBar(this));
|
||||||
|
@ -60,6 +84,19 @@ void MainWindow::initialize()
|
||||||
helper->setSystemButton(m_titleBar->maximizeButton(), SystemButtonType::Maximize);
|
helper->setSystemButton(m_titleBar->maximizeButton(), SystemButtonType::Maximize);
|
||||||
helper->setSystemButton(m_titleBar->closeButton(), SystemButtonType::Close);
|
helper->setSystemButton(m_titleBar->closeButton(), SystemButtonType::Close);
|
||||||
helper->setHitTestVisible(mb); // IMPORTANT!
|
helper->setHitTestVisible(mb); // IMPORTANT!
|
||||||
|
connect(helper, &FramelessWidgetsHelper::ready, this, [this, helper](){
|
||||||
|
const QScopedPointer<QSettings> settings(appConfigFile());
|
||||||
|
const QByteArray geoData = settings->value(kGeoKeyPath).toByteArray();
|
||||||
|
const QByteArray stateData = settings->value(kStateKeyPath).toByteArray();
|
||||||
|
if (geoData.isEmpty()) {
|
||||||
|
helper->moveWindowToDesktopCenter();
|
||||||
|
} else {
|
||||||
|
restoreGeometry(geoData);
|
||||||
|
}
|
||||||
|
if (!stateData.isEmpty()) {
|
||||||
|
restoreState(stateData);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
setWindowTitle(tr("FramelessHelper demo application - Qt MainWindow"));
|
setWindowTitle(tr("FramelessHelper demo application - Qt MainWindow"));
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,6 +44,9 @@ public:
|
||||||
explicit MainWindow(QWidget *parent = nullptr, const Qt::WindowFlags flags = {});
|
explicit MainWindow(QWidget *parent = nullptr, const Qt::WindowFlags flags = {});
|
||||||
~MainWindow() override;
|
~MainWindow() override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void closeEvent(QCloseEvent *event) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void initialize();
|
void initialize();
|
||||||
|
|
||||||
|
|
|
@ -52,8 +52,6 @@
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QSurfaceFormat>
|
#include <QSurfaceFormat>
|
||||||
#include <QOpenGLContext>
|
#include <QOpenGLContext>
|
||||||
#include <framelesshelpercore_global.h>
|
|
||||||
#include <framelessconfig_p.h>
|
|
||||||
#include "mainwindow.h"
|
#include "mainwindow.h"
|
||||||
|
|
||||||
// This example demonstrates easy, cross-platform usage of OpenGL ES 3.0 functions via
|
// This example demonstrates easy, cross-platform usage of OpenGL ES 3.0 functions via
|
||||||
|
@ -66,8 +64,6 @@
|
||||||
|
|
||||||
FRAMELESSHELPER_USE_NAMESPACE
|
FRAMELESSHELPER_USE_NAMESPACE
|
||||||
|
|
||||||
using namespace Global;
|
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
// Not necessary, but better call this function, before the construction
|
// Not necessary, but better call this function, before the construction
|
||||||
|
@ -76,8 +72,6 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
QApplication application(argc, argv);
|
QApplication application(argc, argv);
|
||||||
|
|
||||||
FramelessConfig::instance()->set(Option::CenterWindowBeforeShow);
|
|
||||||
|
|
||||||
QSurfaceFormat fmt = {};
|
QSurfaceFormat fmt = {};
|
||||||
fmt.setDepthBufferSize(24);
|
fmt.setDepthBufferSize(24);
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,10 @@
|
||||||
|
|
||||||
#include "mainwindow.h"
|
#include "mainwindow.h"
|
||||||
#include "glwidget.h"
|
#include "glwidget.h"
|
||||||
|
#include <QtCore/qsettings.h>
|
||||||
|
#include <QtCore/qcoreapplication.h>
|
||||||
|
#include <QtCore/qfileinfo.h>
|
||||||
|
#include <QtCore/qdir.h>
|
||||||
#include <QtWidgets/qboxlayout.h>
|
#include <QtWidgets/qboxlayout.h>
|
||||||
#include <FramelessWidgetsHelper>
|
#include <FramelessWidgetsHelper>
|
||||||
#include <StandardTitleBar>
|
#include <StandardTitleBar>
|
||||||
|
@ -33,6 +37,17 @@ FRAMELESSHELPER_USE_NAMESPACE
|
||||||
|
|
||||||
using namespace Global;
|
using namespace Global;
|
||||||
|
|
||||||
|
FRAMELESSHELPER_STRING_CONSTANT2(IniKeyPath, "Window/Geometry")
|
||||||
|
|
||||||
|
[[nodiscard]] static inline QSettings *appConfigFile()
|
||||||
|
{
|
||||||
|
const QFileInfo fileInfo(QCoreApplication::applicationFilePath());
|
||||||
|
const QString iniFileName = fileInfo.completeBaseName() + FRAMELESSHELPER_STRING_LITERAL(".ini");
|
||||||
|
const QString iniFilePath = fileInfo.canonicalPath() + QDir::separator() + iniFileName;
|
||||||
|
const auto settings = new QSettings(iniFilePath, QSettings::IniFormat);
|
||||||
|
return settings;
|
||||||
|
}
|
||||||
|
|
||||||
MainWindow::MainWindow(QWidget *parent) : FramelessWidget(parent)
|
MainWindow::MainWindow(QWidget *parent) : FramelessWidget(parent)
|
||||||
{
|
{
|
||||||
initialize();
|
initialize();
|
||||||
|
@ -40,6 +55,13 @@ MainWindow::MainWindow(QWidget *parent) : FramelessWidget(parent)
|
||||||
|
|
||||||
MainWindow::~MainWindow() = default;
|
MainWindow::~MainWindow() = default;
|
||||||
|
|
||||||
|
void MainWindow::closeEvent(QCloseEvent *event)
|
||||||
|
{
|
||||||
|
const QScopedPointer<QSettings> settings(appConfigFile());
|
||||||
|
settings->setValue(kIniKeyPath, saveGeometry());
|
||||||
|
FramelessWidget::closeEvent(event);
|
||||||
|
}
|
||||||
|
|
||||||
void MainWindow::initialize()
|
void MainWindow::initialize()
|
||||||
{
|
{
|
||||||
resize(800, 600);
|
resize(800, 600);
|
||||||
|
@ -58,4 +80,13 @@ void MainWindow::initialize()
|
||||||
helper->setSystemButton(m_titleBar->minimizeButton(), SystemButtonType::Minimize);
|
helper->setSystemButton(m_titleBar->minimizeButton(), SystemButtonType::Minimize);
|
||||||
helper->setSystemButton(m_titleBar->maximizeButton(), SystemButtonType::Maximize);
|
helper->setSystemButton(m_titleBar->maximizeButton(), SystemButtonType::Maximize);
|
||||||
helper->setSystemButton(m_titleBar->closeButton(), SystemButtonType::Close);
|
helper->setSystemButton(m_titleBar->closeButton(), SystemButtonType::Close);
|
||||||
|
connect(helper, &FramelessWidgetsHelper::ready, this, [this, helper](){
|
||||||
|
const QScopedPointer<QSettings> settings(appConfigFile());
|
||||||
|
const QByteArray data = settings->value(kIniKeyPath).toByteArray();
|
||||||
|
if (data.isEmpty()) {
|
||||||
|
helper->moveWindowToDesktopCenter();
|
||||||
|
} else {
|
||||||
|
restoreGeometry(data);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,6 +41,9 @@ public:
|
||||||
explicit MainWindow(QWidget *parent = nullptr);
|
explicit MainWindow(QWidget *parent = nullptr);
|
||||||
~MainWindow() override;
|
~MainWindow() override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void closeEvent(QCloseEvent *event) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void initialize();
|
void initialize();
|
||||||
|
|
||||||
|
|
|
@ -28,6 +28,8 @@ find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS QuickControls2)
|
||||||
set(SOURCES
|
set(SOURCES
|
||||||
qml.qrc
|
qml.qrc
|
||||||
main.cpp
|
main.cpp
|
||||||
|
settings.h
|
||||||
|
settings.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
|
|
|
@ -26,14 +26,33 @@ import QtQuick 2.0
|
||||||
import QtQuick.Window 2.0
|
import QtQuick.Window 2.0
|
||||||
import QtQuick.Controls 2.0
|
import QtQuick.Controls 2.0
|
||||||
import org.wangwenx190.FramelessHelper 1.0
|
import org.wangwenx190.FramelessHelper 1.0
|
||||||
|
import Demo 1.0
|
||||||
|
|
||||||
FramelessWindow {
|
FramelessWindow {
|
||||||
id: window
|
id: window
|
||||||
|
visible: false // Hide the window before we sets up it's correct size and position.
|
||||||
width: 800
|
width: 800
|
||||||
height: 600
|
height: 600
|
||||||
title: qsTr("FramelessHelper demo application - Qt Quick")
|
title: qsTr("FramelessHelper demo application - Qt Quick")
|
||||||
color: (FramelessUtils.systemTheme === FramelessHelperConstants.Dark)
|
color: (FramelessUtils.systemTheme === FramelessHelperConstants.Dark)
|
||||||
? FramelessUtils.defaultSystemDarkColor : FramelessUtils.defaultSystemLightColor
|
? FramelessUtils.defaultSystemDarkColor : FramelessUtils.defaultSystemLightColor
|
||||||
|
onClosing: Settings.saveGeometry(window)
|
||||||
|
|
||||||
|
FramelessHelper.onReady: {
|
||||||
|
// Let FramelessHelper know what's our homemade title bar, otherwise
|
||||||
|
// our window won't be draggable.
|
||||||
|
FramelessHelper.titleBarItem = titleBar;
|
||||||
|
// Make our own items visible to the hit test and on Windows, enable
|
||||||
|
// the snap layouts feature (available since Windows 11).
|
||||||
|
FramelessHelper.setSystemButton(titleBar.minimizeButton, FramelessHelperConstants.Minimize);
|
||||||
|
FramelessHelper.setSystemButton(titleBar.maximizeButton, FramelessHelperConstants.Maximize);
|
||||||
|
FramelessHelper.setSystemButton(titleBar.closeButton, FramelessHelperConstants.Close);
|
||||||
|
if (!Settings.restoreGeometry(window)) {
|
||||||
|
FramelessHelper.moveWindowToDesktopCenter();
|
||||||
|
}
|
||||||
|
// Finally, show the window after everything is setted.
|
||||||
|
window.visible = true;
|
||||||
|
}
|
||||||
|
|
||||||
Timer {
|
Timer {
|
||||||
interval: 500
|
interval: 500
|
||||||
|
@ -55,19 +74,9 @@ FramelessWindow {
|
||||||
StandardTitleBar {
|
StandardTitleBar {
|
||||||
id: titleBar
|
id: titleBar
|
||||||
anchors {
|
anchors {
|
||||||
top: window.topBorderBottom
|
top: window.topBorderBottom // IMPORTANT!
|
||||||
left: parent.left
|
left: parent.left
|
||||||
right: parent.right
|
right: parent.right
|
||||||
}
|
}
|
||||||
Component.onCompleted: {
|
|
||||||
// Make our homemade title bar draggable, and open the system menu
|
|
||||||
// when the user right clicks on the title bar area.
|
|
||||||
FramelessHelper.titleBarItem = titleBar;
|
|
||||||
// Make our own items visible to the hit test and on Windows, enable
|
|
||||||
// the snap layout feature (available since Windows 11).
|
|
||||||
FramelessHelper.setSystemButton(titleBar.minimizeButton, FramelessHelperConstants.Minimize);
|
|
||||||
FramelessHelper.setSystemButton(titleBar.maximizeButton, FramelessHelperConstants.Maximize);
|
|
||||||
FramelessHelper.setSystemButton(titleBar.closeButton, FramelessHelperConstants.Close);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,12 +27,10 @@
|
||||||
#include <QtQuick/qquickwindow.h>
|
#include <QtQuick/qquickwindow.h>
|
||||||
#include <QtQuickControls2/qquickstyle.h>
|
#include <QtQuickControls2/qquickstyle.h>
|
||||||
#include <framelessquickmodule.h>
|
#include <framelessquickmodule.h>
|
||||||
#include <framelessconfig_p.h>
|
#include "settings.h"
|
||||||
|
|
||||||
FRAMELESSHELPER_USE_NAMESPACE
|
FRAMELESSHELPER_USE_NAMESPACE
|
||||||
|
|
||||||
using namespace Global;
|
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
// Not necessary, but better call this function, before the construction
|
// Not necessary, but better call this function, before the construction
|
||||||
|
@ -41,8 +39,6 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
QGuiApplication application(argc, argv);
|
QGuiApplication application(argc, argv);
|
||||||
|
|
||||||
FramelessConfig::instance()->set(Option::CenterWindowBeforeShow);
|
|
||||||
|
|
||||||
// Allow testing other RHI backends through environment variable.
|
// Allow testing other RHI backends through environment variable.
|
||||||
if (!qEnvironmentVariableIsSet("QSG_RHI_BACKEND")) {
|
if (!qEnvironmentVariableIsSet("QSG_RHI_BACKEND")) {
|
||||||
// This line is not relevant to FramelessHelper, we change
|
// This line is not relevant to FramelessHelper, we change
|
||||||
|
@ -63,6 +59,13 @@ int main(int argc, char *argv[])
|
||||||
// Don't forget to register our own custom QML types!
|
// Don't forget to register our own custom QML types!
|
||||||
FramelessHelper::Quick::registerTypes(&engine);
|
FramelessHelper::Quick::registerTypes(&engine);
|
||||||
|
|
||||||
|
qmlRegisterSingletonType<Settings>("Demo", 1, 0, "Settings",
|
||||||
|
[](QQmlEngine *engine, QJSEngine *scriptEngine) -> QObject * {
|
||||||
|
Q_UNUSED(engine);
|
||||||
|
Q_UNUSED(scriptEngine);
|
||||||
|
return new Settings;
|
||||||
|
});
|
||||||
|
|
||||||
// This line is not relevant to FramelessHelper, we change the default
|
// This line is not relevant to FramelessHelper, we change the default
|
||||||
// Qt Quick Controls theme to "Basic" (Qt6) or "Default" (Qt5) just
|
// Qt Quick Controls theme to "Basic" (Qt6) or "Default" (Qt5) just
|
||||||
// because other themes will make our homemade system buttons look
|
// because other themes will make our homemade system buttons look
|
||||||
|
@ -73,11 +76,11 @@ int main(int argc, char *argv[])
|
||||||
QQuickStyle::setStyle(FRAMELESSHELPER_STRING_LITERAL("Default"));
|
QQuickStyle::setStyle(FRAMELESSHELPER_STRING_LITERAL("Default"));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
const QUrl homepageUrl(FRAMELESSHELPER_STRING_LITERAL("qrc:///Demo/qml/MainWindow.qml"));
|
const QUrl mainUrl(FRAMELESSHELPER_STRING_LITERAL("qrc:///Demo/qml/MainWindow.qml"));
|
||||||
const QMetaObject::Connection connection = QObject::connect(
|
const QMetaObject::Connection connection = QObject::connect(
|
||||||
&engine, &QQmlApplicationEngine::objectCreated, &application,
|
&engine, &QQmlApplicationEngine::objectCreated, &application,
|
||||||
[&homepageUrl, &connection](QObject *object, const QUrl &url) {
|
[&mainUrl, &connection](QObject *object, const QUrl &url) {
|
||||||
if (url != homepageUrl) {
|
if (url != mainUrl) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (object) {
|
if (object) {
|
||||||
|
@ -87,7 +90,7 @@ int main(int argc, char *argv[])
|
||||||
}
|
}
|
||||||
}, Qt::QueuedConnection);
|
}, Qt::QueuedConnection);
|
||||||
|
|
||||||
engine.load(homepageUrl);
|
engine.load(mainUrl);
|
||||||
|
|
||||||
return QCoreApplication::exec();
|
return QCoreApplication::exec();
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,77 @@
|
||||||
|
/*
|
||||||
|
* MIT License
|
||||||
|
*
|
||||||
|
* Copyright (C) 2022 by wangwenx190 (Yuhang Zhao)
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "settings.h"
|
||||||
|
#include <QtCore/qsettings.h>
|
||||||
|
#include <QtCore/qcoreapplication.h>
|
||||||
|
#include <QtCore/qfileinfo.h>
|
||||||
|
#include <QtCore/qdir.h>
|
||||||
|
#include <QtCore/qdatastream.h>
|
||||||
|
#include <QtGui/qwindow.h>
|
||||||
|
|
||||||
|
FRAMELESSHELPER_STRING_CONSTANT2(IniKeyPath, "Window/Geometry")
|
||||||
|
|
||||||
|
Settings::Settings(QObject *parent) : QObject(parent)
|
||||||
|
{
|
||||||
|
const QFileInfo fileInfo(QCoreApplication::applicationFilePath());
|
||||||
|
const QString iniFileName = fileInfo.completeBaseName() + FRAMELESSHELPER_STRING_LITERAL(".ini");
|
||||||
|
const QString iniFilePath = fileInfo.canonicalPath() + QDir::separator() + iniFileName;
|
||||||
|
m_settings.reset(new QSettings(iniFilePath, QSettings::IniFormat));
|
||||||
|
}
|
||||||
|
|
||||||
|
Settings::~Settings() = default;
|
||||||
|
|
||||||
|
void Settings::saveGeometry(QWindow *window)
|
||||||
|
{
|
||||||
|
Q_ASSERT(window);
|
||||||
|
if (!window) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
QByteArray data = {};
|
||||||
|
QDataStream stream(&data, QDataStream::WriteOnly);
|
||||||
|
stream.setVersion(QDataStream::Qt_5_6);
|
||||||
|
stream << window->geometry();
|
||||||
|
m_settings->setValue(kIniKeyPath, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Settings::restoreGeometry(QWindow *window)
|
||||||
|
{
|
||||||
|
Q_ASSERT(window);
|
||||||
|
if (!window) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const QByteArray data = m_settings->value(kIniKeyPath).toByteArray();
|
||||||
|
if (data.isEmpty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
QRect geometry = {};
|
||||||
|
QDataStream stream(data);
|
||||||
|
stream.setVersion(QDataStream::Qt_5_6);
|
||||||
|
stream >> geometry;
|
||||||
|
if (!geometry.isValid()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
window->setGeometry(geometry);
|
||||||
|
return true;
|
||||||
|
}
|
|
@ -0,0 +1,50 @@
|
||||||
|
/*
|
||||||
|
* MIT License
|
||||||
|
*
|
||||||
|
* Copyright (C) 2022 by wangwenx190 (Yuhang Zhao)
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QtCore/qobject.h>
|
||||||
|
#include <framelesshelpercore_global.h>
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
class QWindow;
|
||||||
|
class QSettings;
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
|
class Settings : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
Q_DISABLE_COPY_MOVE(Settings)
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit Settings(QObject *parent = nullptr);
|
||||||
|
~Settings() override;
|
||||||
|
|
||||||
|
public Q_SLOTS:
|
||||||
|
void saveGeometry(QWindow *window);
|
||||||
|
Q_NODISCARD bool restoreGeometry(QWindow *window);
|
||||||
|
|
||||||
|
private:
|
||||||
|
QScopedPointer<QSettings> m_settings;
|
||||||
|
};
|
|
@ -23,13 +23,10 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <QtWidgets/qapplication.h>
|
#include <QtWidgets/qapplication.h>
|
||||||
#include <framelessconfig_p.h>
|
|
||||||
#include "widget.h"
|
#include "widget.h"
|
||||||
|
|
||||||
FRAMELESSHELPER_USE_NAMESPACE
|
FRAMELESSHELPER_USE_NAMESPACE
|
||||||
|
|
||||||
using namespace Global;
|
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
// Not necessary, but better call this function, before the construction
|
// Not necessary, but better call this function, before the construction
|
||||||
|
@ -38,8 +35,6 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
QApplication application(argc, argv);
|
QApplication application(argc, argv);
|
||||||
|
|
||||||
FramelessConfig::instance()->set(Option::CenterWindowBeforeShow);
|
|
||||||
|
|
||||||
Widget widget;
|
Widget widget;
|
||||||
widget.show();
|
widget.show();
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,10 @@
|
||||||
|
|
||||||
#include "widget.h"
|
#include "widget.h"
|
||||||
#include <QtCore/qdatetime.h>
|
#include <QtCore/qdatetime.h>
|
||||||
|
#include <QtCore/qsettings.h>
|
||||||
|
#include <QtCore/qcoreapplication.h>
|
||||||
|
#include <QtCore/qfileinfo.h>
|
||||||
|
#include <QtCore/qdir.h>
|
||||||
#include <QtWidgets/qlabel.h>
|
#include <QtWidgets/qlabel.h>
|
||||||
#include <QtWidgets/qboxlayout.h>
|
#include <QtWidgets/qboxlayout.h>
|
||||||
#include <FramelessManager>
|
#include <FramelessManager>
|
||||||
|
@ -36,6 +40,17 @@ FRAMELESSHELPER_USE_NAMESPACE
|
||||||
|
|
||||||
using namespace Global;
|
using namespace Global;
|
||||||
|
|
||||||
|
FRAMELESSHELPER_STRING_CONSTANT2(IniKeyPath, "Window/Geometry")
|
||||||
|
|
||||||
|
[[nodiscard]] static inline QSettings *appConfigFile()
|
||||||
|
{
|
||||||
|
const QFileInfo fileInfo(QCoreApplication::applicationFilePath());
|
||||||
|
const QString iniFileName = fileInfo.completeBaseName() + FRAMELESSHELPER_STRING_LITERAL(".ini");
|
||||||
|
const QString iniFilePath = fileInfo.canonicalPath() + QDir::separator() + iniFileName;
|
||||||
|
const auto settings = new QSettings(iniFilePath, QSettings::IniFormat);
|
||||||
|
return settings;
|
||||||
|
}
|
||||||
|
|
||||||
Widget::Widget(QWidget *parent) : FramelessWidget(parent)
|
Widget::Widget(QWidget *parent) : FramelessWidget(parent)
|
||||||
{
|
{
|
||||||
initialize();
|
initialize();
|
||||||
|
@ -53,6 +68,13 @@ void Widget::timerEvent(QTimerEvent *event)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Widget::closeEvent(QCloseEvent *event)
|
||||||
|
{
|
||||||
|
const QScopedPointer<QSettings> settings(appConfigFile());
|
||||||
|
settings->setValue(kIniKeyPath, saveGeometry());
|
||||||
|
FramelessWidget::closeEvent(event);
|
||||||
|
}
|
||||||
|
|
||||||
void Widget::initialize()
|
void Widget::initialize()
|
||||||
{
|
{
|
||||||
setWindowTitle(tr("FramelessHelper demo application - Qt Widgets"));
|
setWindowTitle(tr("FramelessHelper demo application - Qt Widgets"));
|
||||||
|
@ -83,6 +105,15 @@ void Widget::initialize()
|
||||||
helper->setSystemButton(m_titleBar->minimizeButton(), SystemButtonType::Minimize);
|
helper->setSystemButton(m_titleBar->minimizeButton(), SystemButtonType::Minimize);
|
||||||
helper->setSystemButton(m_titleBar->maximizeButton(), SystemButtonType::Maximize);
|
helper->setSystemButton(m_titleBar->maximizeButton(), SystemButtonType::Maximize);
|
||||||
helper->setSystemButton(m_titleBar->closeButton(), SystemButtonType::Close);
|
helper->setSystemButton(m_titleBar->closeButton(), SystemButtonType::Close);
|
||||||
|
connect(helper, &FramelessWidgetsHelper::ready, this, [this, helper](){
|
||||||
|
const QScopedPointer<QSettings> settings(appConfigFile());
|
||||||
|
const QByteArray data = settings->value(kIniKeyPath).toByteArray();
|
||||||
|
if (data.isEmpty()) {
|
||||||
|
helper->moveWindowToDesktopCenter();
|
||||||
|
} else {
|
||||||
|
restoreGeometry(data);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void Widget::updateStyleSheet()
|
void Widget::updateStyleSheet()
|
||||||
|
|
|
@ -45,6 +45,7 @@ public:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void timerEvent(QTimerEvent *event) override;
|
void timerEvent(QTimerEvent *event) override;
|
||||||
|
void closeEvent(QCloseEvent *event) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void initialize();
|
void initialize();
|
||||||
|
|
|
@ -71,6 +71,7 @@ protected:
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void titleBarItemChanged();
|
void titleBarItemChanged();
|
||||||
|
void ready();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QScopedPointer<FramelessQuickHelperPrivate> d_ptr;
|
QScopedPointer<FramelessQuickHelperPrivate> d_ptr;
|
||||||
|
|
|
@ -65,6 +65,8 @@ public:
|
||||||
Q_NODISCARD bool isWindowFixedSize() const;
|
Q_NODISCARD bool isWindowFixedSize() const;
|
||||||
void setWindowFixedSize(const bool value);
|
void setWindowFixedSize(const bool value);
|
||||||
|
|
||||||
|
void emitSignalForAllInstances(const char *signal);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Q_NODISCARD QRect mapItemGeometryToScene(const QQuickItem * const item) const;
|
Q_NODISCARD QRect mapItemGeometryToScene(const QQuickItem * const item) const;
|
||||||
Q_NODISCARD bool isInSystemButtons(const QPoint &pos, QuickGlobal::SystemButtonType *button) const;
|
Q_NODISCARD bool isInSystemButtons(const QPoint &pos, QuickGlobal::SystemButtonType *button) const;
|
||||||
|
|
|
@ -64,6 +64,7 @@ public Q_SLOTS:
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void titleBarWidgetChanged();
|
void titleBarWidgetChanged();
|
||||||
|
void ready();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QScopedPointer<FramelessWidgetsHelperPrivate> d_ptr;
|
QScopedPointer<FramelessWidgetsHelperPrivate> d_ptr;
|
||||||
|
|
|
@ -61,6 +61,8 @@ public:
|
||||||
Q_NODISCARD bool isWindowFixedSize() const;
|
Q_NODISCARD bool isWindowFixedSize() const;
|
||||||
void setWindowFixedSize(const bool value);
|
void setWindowFixedSize(const bool value);
|
||||||
|
|
||||||
|
void emitSignalForAllInstances(const char *signal);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Q_NODISCARD QRect mapWidgetGeometryToScene(const QWidget * const widget) const;
|
Q_NODISCARD QRect mapWidgetGeometryToScene(const QWidget * const widget) const;
|
||||||
Q_NODISCARD bool isInSystemButtons(const QPoint &pos, Global::SystemButtonType *button) const;
|
Q_NODISCARD bool isInSystemButtons(const QPoint &pos, Global::SystemButtonType *button) const;
|
||||||
|
|
|
@ -163,7 +163,7 @@ FRAMELESSHELPER_STRING_CONSTANT(FindWindowW)
|
||||||
switch (uMsg) {
|
switch (uMsg) {
|
||||||
case WM_NCHITTEST: {
|
case WM_NCHITTEST: {
|
||||||
// Try to determine what part of the window is being hovered here. This
|
// Try to determine what part of the window is being hovered here. This
|
||||||
// is absolutely critical to making sure the snap layout works!
|
// is absolutely critical to making sure the snap layouts works!
|
||||||
const POINT nativeGlobalPos = {GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)};
|
const POINT nativeGlobalPos = {GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)};
|
||||||
POINT nativeLocalPos = nativeGlobalPos;
|
POINT nativeLocalPos = nativeGlobalPos;
|
||||||
if (ScreenToClient(hWnd, &nativeLocalPos) == FALSE) {
|
if (ScreenToClient(hWnd, &nativeLocalPos) == FALSE) {
|
||||||
|
@ -371,7 +371,7 @@ FRAMELESSHELPER_STRING_CONSTANT(FindWindowW)
|
||||||
const auto dragBarWindowHandle = reinterpret_cast<HWND>(dragBarWindowId);
|
const auto dragBarWindowHandle = reinterpret_cast<HWND>(dragBarWindowId);
|
||||||
const UINT flags = (SWP_NOACTIVATE | (hide ? SWP_HIDEWINDOW : SWP_SHOWWINDOW));
|
const UINT flags = (SWP_NOACTIVATE | (hide ? SWP_HIDEWINDOW : SWP_SHOWWINDOW));
|
||||||
// As you can see from the code, we only use the drag bar window to activate the
|
// As you can see from the code, we only use the drag bar window to activate the
|
||||||
// snap layout feature introduced in Windows 11. So you may wonder, why not just
|
// snap layouts feature introduced in Windows 11. So you may wonder, why not just
|
||||||
// limit it to the rectangle of the three system buttons, instead of covering the
|
// limit it to the rectangle of the three system buttons, instead of covering the
|
||||||
// whole title bar area? Well, I've tried that solution already and unfortunately
|
// whole title bar area? Well, I've tried that solution already and unfortunately
|
||||||
// it doesn't work. Since our current solution works well, I have no plan to dig
|
// it doesn't work. Since our current solution works well, I have no plan to dig
|
||||||
|
@ -536,7 +536,6 @@ bool FramelessHelperWin::nativeEventFilter(const QByteArray &eventType, void *me
|
||||||
const LPARAM lParam = msg->lParam;
|
const LPARAM lParam = msg->lParam;
|
||||||
switch (uMsg) {
|
switch (uMsg) {
|
||||||
case WM_NCCALCSIZE: {
|
case WM_NCCALCSIZE: {
|
||||||
const bool isFixedSize = data.params.isWindowFixedSize();
|
|
||||||
// Windows是根据这个消息的返回值来设置窗口的客户区(窗口中真正显示的内容)
|
// Windows是根据这个消息的返回值来设置窗口的客户区(窗口中真正显示的内容)
|
||||||
// 和非客户区(标题栏、窗口边框、菜单栏和状态栏等Windows系统自行提供的部分
|
// 和非客户区(标题栏、窗口边框、菜单栏和状态栏等Windows系统自行提供的部分
|
||||||
// ,不过对于Qt来说,除了标题栏和窗口边框,非客户区基本也都是自绘的)的范
|
// ,不过对于Qt来说,除了标题栏和窗口边框,非客户区基本也都是自绘的)的范
|
||||||
|
@ -870,8 +869,7 @@ bool FramelessHelperWin::nativeEventFilter(const QByteArray &eventType, void *me
|
||||||
(GetAsyncKeyState(VK_RBUTTON) < 0) : (GetAsyncKeyState(VK_LBUTTON) < 0));
|
(GetAsyncKeyState(VK_RBUTTON) < 0) : (GetAsyncKeyState(VK_LBUTTON) < 0));
|
||||||
const bool isTitleBar = (data.params.isInsideTitleBarDraggableArea(qtScenePos) && leftButtonPressed);
|
const bool isTitleBar = (data.params.isInsideTitleBarDraggableArea(qtScenePos) && leftButtonPressed);
|
||||||
const bool isFixedSize = data.params.isWindowFixedSize();
|
const bool isFixedSize = data.params.isWindowFixedSize();
|
||||||
if( frameBorderVisible )
|
if (frameBorderVisible) {
|
||||||
{
|
|
||||||
// This will handle the left, right and bottom parts of the frame
|
// This will handle the left, right and bottom parts of the frame
|
||||||
// because we didn't change them.
|
// because we didn't change them.
|
||||||
const LRESULT originalRet = DefWindowProcW(hWnd, WM_NCHITTEST, 0, lParam);
|
const LRESULT originalRet = DefWindowProcW(hWnd, WM_NCHITTEST, 0, lParam);
|
||||||
|
@ -1066,8 +1064,7 @@ bool FramelessHelperWin::nativeEventFilter(const QByteArray &eventType, void *me
|
||||||
case WM_DISPLAYCHANGE: // Sent to a window when the display resolution has changed.
|
case WM_DISPLAYCHANGE: // Sent to a window when the display resolution has changed.
|
||||||
{
|
{
|
||||||
const bool isFixedSize = data.params.isWindowFixedSize();
|
const bool isFixedSize = data.params.isWindowFixedSize();
|
||||||
if( !resizeDragBarWindow(windowId, data.dragBarWindowId, isFixedSize) )
|
if (!resizeDragBarWindow(windowId, data.dragBarWindowId, isFixedSize)) {
|
||||||
{
|
|
||||||
qWarning() << "Failed to re-position the drag bar window.";
|
qWarning() << "Failed to re-position the drag bar window.";
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
|
@ -148,8 +148,7 @@ void FramelessQuickHelperPrivate::setTitleBarItem(QQuickItem *value)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
data->titleBarItem = value;
|
data->titleBarItem = value;
|
||||||
Q_Q(FramelessQuickHelper);
|
emitSignalForAllInstances("titleBarItemChanged");
|
||||||
Q_EMIT q->titleBarItemChanged();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void FramelessQuickHelperPrivate::attachToWindow()
|
void FramelessQuickHelperPrivate::attachToWindow()
|
||||||
|
@ -218,11 +217,11 @@ void FramelessQuickHelperPrivate::attachToWindow()
|
||||||
// we reach here, and all the modifications from the Qt side will be lost
|
// we reach here, and all the modifications from the Qt side will be lost
|
||||||
// due to QPA will reset the position and size of the window during it's
|
// due to QPA will reset the position and size of the window during it's
|
||||||
// initialization process.
|
// initialization process.
|
||||||
QTimer::singleShot(0, this, [this, window](){
|
QTimer::singleShot(0, this, [this](){
|
||||||
if (FramelessConfig::instance()->isSet(Option::CenterWindowBeforeShow)) {
|
if (FramelessConfig::instance()->isSet(Option::CenterWindowBeforeShow)) {
|
||||||
moveWindowToDesktopCenter();
|
moveWindowToDesktopCenter();
|
||||||
}
|
}
|
||||||
window->setVisible(true);
|
emitSignalForAllInstances("ready");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -391,6 +390,27 @@ void FramelessQuickHelperPrivate::setWindowFixedSize(const bool value)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FramelessQuickHelperPrivate::emitSignalForAllInstances(const char *signal)
|
||||||
|
{
|
||||||
|
Q_ASSERT(signal);
|
||||||
|
if (!signal) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Q_Q(FramelessQuickHelper);
|
||||||
|
const QQuickWindow * const window = q->window();
|
||||||
|
if (!window) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const auto rootObject = (window->contentItem() ? qobject_cast<const QObject *>(window->contentItem()) : qobject_cast<const QObject *>(window));
|
||||||
|
const auto instances = rootObject->findChildren<FramelessQuickHelper *>();
|
||||||
|
if (instances.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (auto &&instance : qAsConst(instances)) {
|
||||||
|
QMetaObject::invokeMethod(instance, signal);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
QRect FramelessQuickHelperPrivate::mapItemGeometryToScene(const QQuickItem * const item) const
|
QRect FramelessQuickHelperPrivate::mapItemGeometryToScene(const QQuickItem * const item) const
|
||||||
{
|
{
|
||||||
Q_ASSERT(item);
|
Q_ASSERT(item);
|
||||||
|
@ -616,7 +636,7 @@ FramelessQuickHelper *FramelessQuickHelper::get(QObject *object)
|
||||||
QObject *parent = nullptr;
|
QObject *parent = nullptr;
|
||||||
if (isItem(object)) {
|
if (isItem(object)) {
|
||||||
const auto item = qobject_cast<QQuickItem *>(object);
|
const auto item = qobject_cast<QQuickItem *>(object);
|
||||||
parent = (item->window() ? item->window()->contentItem() : item);
|
parent = ((item->window() && item->window()->contentItem()) ? item->window()->contentItem() : item);
|
||||||
} else {
|
} else {
|
||||||
parent = object;
|
parent = object;
|
||||||
}
|
}
|
||||||
|
@ -625,9 +645,8 @@ FramelessQuickHelper *FramelessQuickHelper::get(QObject *object)
|
||||||
instance = new FramelessQuickHelper;
|
instance = new FramelessQuickHelper;
|
||||||
if (isItem(parent)) {
|
if (isItem(parent)) {
|
||||||
instance->setParentItem(qobject_cast<QQuickItem *>(parent));
|
instance->setParentItem(qobject_cast<QQuickItem *>(parent));
|
||||||
} else {
|
|
||||||
instance->setParent(parent);
|
|
||||||
}
|
}
|
||||||
|
instance->setParent(parent);
|
||||||
// No need to do this here, we'll do it once the item has been assigned to a specific window.
|
// No need to do this here, we'll do it once the item has been assigned to a specific window.
|
||||||
//instance->d_func()->attachToWindow();
|
//instance->d_func()->attachToWindow();
|
||||||
}
|
}
|
||||||
|
@ -734,8 +753,16 @@ void FramelessQuickHelper::itemChange(const ItemChange change, const ItemChangeD
|
||||||
{
|
{
|
||||||
QQuickItem::itemChange(change, value);
|
QQuickItem::itemChange(change, value);
|
||||||
if ((change == ItemSceneChange) && value.window) {
|
if ((change == ItemSceneChange) && value.window) {
|
||||||
if (parentItem() != value.window->contentItem()) {
|
QQuickItem * const rootItem = value.window->contentItem();
|
||||||
setParentItem(value.window->contentItem());
|
if (rootItem) {
|
||||||
|
if ((parentItem() != rootItem) || (parent() != rootItem)) {
|
||||||
|
setParentItem(rootItem);
|
||||||
|
setParent(rootItem);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (parent() != value.window) {
|
||||||
|
setParent(value.window);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Q_D(FramelessQuickHelper);
|
Q_D(FramelessQuickHelper);
|
||||||
d->attachToWindow();
|
d->attachToWindow();
|
||||||
|
|
|
@ -128,6 +128,25 @@ void FramelessWidgetsHelperPrivate::setWindowFixedSize(const bool value)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FramelessWidgetsHelperPrivate::emitSignalForAllInstances(const char *signal)
|
||||||
|
{
|
||||||
|
Q_ASSERT(signal);
|
||||||
|
if (!signal) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const QWidget * const window = getWindow();
|
||||||
|
if (!window) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const auto instances = window->findChildren<FramelessWidgetsHelper *>();
|
||||||
|
if (instances.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (auto &&instance : qAsConst(instances)) {
|
||||||
|
QMetaObject::invokeMethod(instance, signal);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void FramelessWidgetsHelperPrivate::setTitleBarWidget(QWidget *widget)
|
void FramelessWidgetsHelperPrivate::setTitleBarWidget(QWidget *widget)
|
||||||
{
|
{
|
||||||
Q_ASSERT(widget);
|
Q_ASSERT(widget);
|
||||||
|
@ -143,8 +162,7 @@ void FramelessWidgetsHelperPrivate::setTitleBarWidget(QWidget *widget)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
data->titleBarWidget = widget;
|
data->titleBarWidget = widget;
|
||||||
Q_Q(FramelessWidgetsHelper);
|
emitSignalForAllInstances("titleBarWidgetChanged");
|
||||||
Q_EMIT q->titleBarWidgetChanged();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QWidget *FramelessWidgetsHelperPrivate::getTitleBarWidget() const
|
QWidget *FramelessWidgetsHelperPrivate::getTitleBarWidget() const
|
||||||
|
@ -245,11 +263,11 @@ void FramelessWidgetsHelperPrivate::attachToWindow()
|
||||||
// we reach here, and all the modifications from the Qt side will be lost
|
// we reach here, and all the modifications from the Qt side will be lost
|
||||||
// due to QPA will reset the position and size of the window during it's
|
// due to QPA will reset the position and size of the window during it's
|
||||||
// initialization process.
|
// initialization process.
|
||||||
QTimer::singleShot(0, this, [this, window](){
|
QTimer::singleShot(0, this, [this](){
|
||||||
if (FramelessConfig::instance()->isSet(Option::CenterWindowBeforeShow)) {
|
if (FramelessConfig::instance()->isSet(Option::CenterWindowBeforeShow)) {
|
||||||
moveWindowToDesktopCenter();
|
moveWindowToDesktopCenter();
|
||||||
}
|
}
|
||||||
window->setVisible(true);
|
emitSignalForAllInstances("ready");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue