fix(@desktop/general): Changing System Appearance on the fly is not working
This is corresponding dotherside part of the issue 1725. So far we had kind of a memory leak, cause objects added to the filter were not deleted ever. When the app is closing, it just removes filters, but doesn't delete them. I faced a logical issue, that we were sending qmlengine pointer to the installEventFilter method, instead object which may or may not rely on the qqmlengine instance, that is fixed also. Fixes: #1725
This commit is contained in:
parent
cba2e276b2
commit
f0e3f04994
|
@ -20,7 +20,8 @@ macro(add_target name type)
|
||||||
include/DOtherSide/DosIQAbstractItemModelImpl.h
|
include/DOtherSide/DosIQAbstractItemModelImpl.h
|
||||||
include/DOtherSide/DosQAbstractItemModel.h
|
include/DOtherSide/DosQAbstractItemModel.h
|
||||||
include/DOtherSide/Utils.h
|
include/DOtherSide/Utils.h
|
||||||
include/DOtherSide/DosDockClicker.h
|
include/DOtherSide/StatusEvents/StatusDockShowAppEvent.h
|
||||||
|
include/DOtherSide/StatusEvents/StatusOSThemeEvent.h
|
||||||
include/DOtherSide/DOtherSideStatusWindow.h
|
include/DOtherSide/DOtherSideStatusWindow.h
|
||||||
include/DOtherSide/DOtherSideSingleInstance.h
|
include/DOtherSide/DOtherSideSingleInstance.h
|
||||||
src/DOtherSide.cpp
|
src/DOtherSide.cpp
|
||||||
|
@ -31,7 +32,8 @@ macro(add_target name type)
|
||||||
src/DosQObjectImpl.cpp
|
src/DosQObjectImpl.cpp
|
||||||
src/DosQAbstractItemModel.cpp
|
src/DosQAbstractItemModel.cpp
|
||||||
src/DosQQuickImageProvider.cpp
|
src/DosQQuickImageProvider.cpp
|
||||||
src/DosDockClicker.cpp
|
src/StatusEvents/StatusDockShowAppEvent.cpp
|
||||||
|
src/StatusEvents/StatusOSThemeEvent.cpp
|
||||||
src/DOtherSideStatusWindow.cpp
|
src/DOtherSideStatusWindow.cpp
|
||||||
src/DOtherSideSingleInstance.cpp
|
src/DOtherSideSingleInstance.cpp
|
||||||
)
|
)
|
||||||
|
|
|
@ -82,11 +82,11 @@ DOS_API void DOS_CALL dos_qguiapplication_delete(void);
|
||||||
|
|
||||||
DOS_API void DOS_CALL dos_qguiapplication_icon(const char *filename);
|
DOS_API void DOS_CALL dos_qguiapplication_icon(const char *filename);
|
||||||
|
|
||||||
DOS_API void dos_qguiapplication_installEventFilter(DosQQmlApplicationEngine *vptr);
|
DOS_API void dos_qguiapplication_installEventFilter(DosStatusEventObject *vptr);
|
||||||
|
|
||||||
DOS_API void dos_qapplication_clipboard_setText(const char* text);
|
DOS_API void dos_qapplication_clipboard_setText(const char* text);
|
||||||
|
|
||||||
DOS_API void dos_qapplication_installEventFilter(DosQQmlApplicationEngine *vptr);
|
DOS_API void dos_qapplication_installEventFilter(DosStatusEventObject *vptr);
|
||||||
|
|
||||||
/// @}
|
/// @}
|
||||||
|
|
||||||
|
@ -993,6 +993,11 @@ DOS_API void DOS_CALL dos_singleinstance_delete(DosSingleInstance *vptr);
|
||||||
|
|
||||||
/// @}
|
/// @}
|
||||||
|
|
||||||
|
/// Status event object
|
||||||
|
DOS_API DosStatusEventObject* dos_statusevent_create_showAppEvent(DosQQmlApplicationEngine* vptr);
|
||||||
|
DOS_API DosStatusEventObject* dos_statusevent_create_osThemeEvent(DosQQmlApplicationEngine* vptr);
|
||||||
|
DOS_API void dos_statusevent_delete(DosStatusEventObject* vptr);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -98,6 +98,9 @@ typedef void DosPixmap;
|
||||||
/// A pointer to SingleInstance
|
/// A pointer to SingleInstance
|
||||||
typedef void DosSingleInstance;
|
typedef void DosSingleInstance;
|
||||||
|
|
||||||
|
/// A pointer to a status event object which is actualy a QObject
|
||||||
|
typedef void DosStatusEventObject;
|
||||||
|
|
||||||
/// A pixmap callback to be supplied to an image provider
|
/// A pixmap callback to be supplied to an image provider
|
||||||
/// \param id Image source id
|
/// \param id Image source id
|
||||||
/// \param width pointer to the width of the image
|
/// \param width pointer to the width of the image
|
||||||
|
|
|
@ -1,27 +0,0 @@
|
||||||
#ifndef DOCKCLICKER_H
|
|
||||||
#define DOCKCLICKER_H
|
|
||||||
|
|
||||||
#include <QObject>
|
|
||||||
|
|
||||||
#include <QQmlApplicationEngine>
|
|
||||||
#include "DOtherSideTypes.h"
|
|
||||||
|
|
||||||
class DockClicker : public QObject
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
private:
|
|
||||||
Qt::ApplicationState _prevAppState;
|
|
||||||
QQmlApplicationEngine* _engine;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
bool eventFilter(QObject *obj, QEvent *event) override;
|
|
||||||
|
|
||||||
public:
|
|
||||||
DockClicker(DosQQmlApplicationEngine *vptr) {
|
|
||||||
auto engine = static_cast<QQmlApplicationEngine *>(vptr);
|
|
||||||
_engine = engine;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // DOCKCLICKER_H
|
|
24
vendor/DOtherSide/lib/include/DOtherSide/StatusEvents/StatusDockShowAppEvent.h
vendored
Normal file
24
vendor/DOtherSide/lib/include/DOtherSide/StatusEvents/StatusDockShowAppEvent.h
vendored
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
#ifndef STATUS_DOCK_SHOW_APP_EVENT_H
|
||||||
|
#define STATUS_DOCK_SHOW_APP_EVENT_H
|
||||||
|
|
||||||
|
#include "../DOtherSideTypes.h"
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QQmlApplicationEngine>
|
||||||
|
|
||||||
|
class StatusDockShowAppEvent : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
StatusDockShowAppEvent(DosQQmlApplicationEngine* vptr, QObject* parent = nullptr);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool eventFilter(QObject* obj, QEvent* event) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
Qt::ApplicationState m_prevAppState;
|
||||||
|
QQmlApplicationEngine* m_engine;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,23 @@
|
||||||
|
#ifndef STATUS_OS_THEME_EVENT_H
|
||||||
|
#define STATUS_OS_THEME_EVENT_H
|
||||||
|
|
||||||
|
#include "../DOtherSideTypes.h"
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QQmlApplicationEngine>
|
||||||
|
|
||||||
|
class StatusOSThemeEvent : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
StatusOSThemeEvent(DosQQmlApplicationEngine* vptr, QObject* parent = nullptr);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool eventFilter(QObject* obj, QEvent* event) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QQmlApplicationEngine* m_engine;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -57,10 +57,12 @@
|
||||||
#include "DOtherSide/DosQAbstractItemModel.h"
|
#include "DOtherSide/DosQAbstractItemModel.h"
|
||||||
#include "DOtherSide/DosQDeclarative.h"
|
#include "DOtherSide/DosQDeclarative.h"
|
||||||
#include "DOtherSide/DosQQuickImageProvider.h"
|
#include "DOtherSide/DosQQuickImageProvider.h"
|
||||||
#include "DOtherSide/DosDockClicker.h"
|
|
||||||
#include "DOtherSide/DOtherSideStatusWindow.h"
|
#include "DOtherSide/DOtherSideStatusWindow.h"
|
||||||
#include "DOtherSide/DOtherSideSingleInstance.h"
|
#include "DOtherSide/DOtherSideSingleInstance.h"
|
||||||
|
|
||||||
|
#include "DOtherSide/StatusEvents/StatusDockShowAppEvent.h"
|
||||||
|
#include "DOtherSide/StatusEvents/StatusOSThemeEvent.h"
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
void register_meta_types()
|
void register_meta_types()
|
||||||
|
@ -155,7 +157,8 @@ void dos_qguiapplication_exec()
|
||||||
|
|
||||||
void dos_qguiapplication_quit()
|
void dos_qguiapplication_quit()
|
||||||
{
|
{
|
||||||
qGuiApp->quit();
|
// This way we will be safe for quitting the app (avoid potential crashes).
|
||||||
|
QMetaObject::invokeMethod(qGuiApp, "quit", Qt::QueuedConnection);
|
||||||
}
|
}
|
||||||
|
|
||||||
void dos_qguiapplication_icon(const char *filename)
|
void dos_qguiapplication_icon(const char *filename)
|
||||||
|
@ -163,10 +166,10 @@ void dos_qguiapplication_icon(const char *filename)
|
||||||
qGuiApp->setWindowIcon(QIcon(filename));
|
qGuiApp->setWindowIcon(QIcon(filename));
|
||||||
}
|
}
|
||||||
|
|
||||||
void dos_qguiapplication_installEventFilter(::DosQQmlApplicationEngine *vptr)
|
void dos_qguiapplication_installEventFilter(::DosStatusEventObject* vptr)
|
||||||
{
|
{
|
||||||
DockClicker *dockClicker = new DockClicker(vptr);
|
auto qobject = static_cast<QObject*>(vptr);
|
||||||
qGuiApp->installEventFilter(dockClicker);
|
qGuiApp->installEventFilter(qobject);
|
||||||
}
|
}
|
||||||
|
|
||||||
void dos_qapplication_create()
|
void dos_qapplication_create()
|
||||||
|
@ -196,13 +199,14 @@ void dos_qapplication_icon(const char *filename)
|
||||||
|
|
||||||
void dos_qapplication_quit()
|
void dos_qapplication_quit()
|
||||||
{
|
{
|
||||||
qApp->quit();
|
// This way we will be safe for quitting the app (avoid potential crashes).
|
||||||
|
QMetaObject::invokeMethod(qApp, "quit", Qt::QueuedConnection);
|
||||||
}
|
}
|
||||||
|
|
||||||
void dos_qapplication_installEventFilter(::DosQQmlApplicationEngine *vptr)
|
void dos_qapplication_installEventFilter(::DosStatusEventObject* vptr)
|
||||||
{
|
{
|
||||||
DockClicker *dockClicker = new DockClicker(vptr);
|
auto qobject = static_cast<QObject*>(vptr);
|
||||||
qApp->installEventFilter(dockClicker);
|
qApp->installEventFilter(qobject);
|
||||||
}
|
}
|
||||||
|
|
||||||
::DosQQmlApplicationEngine *dos_qqmlapplicationengine_create()
|
::DosQQmlApplicationEngine *dos_qqmlapplicationengine_create()
|
||||||
|
@ -1313,3 +1317,21 @@ bool dos_singleinstance_isfirst(DosSingleInstance *vptr)
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
::DosStatusEventObject* dos_statusevent_create_showAppEvent(::DosQQmlApplicationEngine* vptr)
|
||||||
|
{
|
||||||
|
auto engine = static_cast<QQmlApplicationEngine*>(vptr);
|
||||||
|
return new StatusDockShowAppEvent(engine);
|
||||||
|
}
|
||||||
|
|
||||||
|
::DosStatusEventObject* dos_statusevent_create_osThemeEvent(::DosQQmlApplicationEngine* vptr)
|
||||||
|
{
|
||||||
|
auto engine = static_cast<QQmlApplicationEngine*>(vptr);
|
||||||
|
return new StatusOSThemeEvent(engine);
|
||||||
|
}
|
||||||
|
|
||||||
|
void dos_statusevent_delete(DosStatusEventObject* vptr)
|
||||||
|
{
|
||||||
|
auto qobject = static_cast<QObject*>(vptr);
|
||||||
|
qobject->deleteLater();
|
||||||
|
}
|
||||||
|
|
|
@ -1,27 +0,0 @@
|
||||||
#include "DOtherSide/DosDockClicker.h"
|
|
||||||
|
|
||||||
#include <QQuickWindow>
|
|
||||||
#include <QCoreApplication>
|
|
||||||
|
|
||||||
|
|
||||||
bool DockClicker::eventFilter(QObject *obj, QEvent *event)
|
|
||||||
{
|
|
||||||
#ifdef Q_OS_MACOS
|
|
||||||
if (obj == qApp) {
|
|
||||||
if (event->type() == QEvent::ApplicationStateChange) {
|
|
||||||
auto ev = static_cast<QApplicationStateChangeEvent*>(event);
|
|
||||||
if (_prevAppState == Qt::ApplicationActive && ev->applicationState() == Qt::ApplicationActive) {
|
|
||||||
QObject *topLevel = _engine->rootObjects().value(0);
|
|
||||||
QQuickWindow *window = qobject_cast<QQuickWindow *>(topLevel);
|
|
||||||
window->setVisible(true);
|
|
||||||
window->showNormal();
|
|
||||||
}
|
|
||||||
_prevAppState = ev->applicationState();
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif // Q_OS_MACOS
|
|
||||||
return QObject::eventFilter(obj, event);
|
|
||||||
}
|
|
|
@ -0,0 +1,45 @@
|
||||||
|
#include "DOtherSide/StatusEvents/StatusDockShowAppEvent.h"
|
||||||
|
|
||||||
|
#include <QQuickWindow>
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Code here is exactly the same as it was before, logic is not changed. I only
|
||||||
|
put it in another form, nothing else. To match an improved flow for
|
||||||
|
installing filters.
|
||||||
|
*/
|
||||||
|
|
||||||
|
StatusDockShowAppEvent::StatusDockShowAppEvent(DosQQmlApplicationEngine* vptr,
|
||||||
|
QObject* parent)
|
||||||
|
: QObject(parent)
|
||||||
|
{
|
||||||
|
m_engine = static_cast<QQmlApplicationEngine*>(vptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool StatusDockShowAppEvent::eventFilter(QObject* obj, QEvent* event)
|
||||||
|
{
|
||||||
|
#ifdef Q_OS_MACOS
|
||||||
|
if (event->type() == QEvent::ApplicationStateChange)
|
||||||
|
{
|
||||||
|
auto ev = static_cast<QApplicationStateChangeEvent*>(event);
|
||||||
|
if (m_prevAppState == Qt::ApplicationActive
|
||||||
|
&& ev->applicationState() == Qt::ApplicationActive)
|
||||||
|
{
|
||||||
|
QObject* topLevelObj = m_engine->rootObjects().value(0);
|
||||||
|
if(topLevelObj && topLevelObj->objectName() == "mainWindow")
|
||||||
|
{
|
||||||
|
QQuickWindow* window = qobject_cast<QQuickWindow *>(topLevelObj);
|
||||||
|
if(window)
|
||||||
|
{
|
||||||
|
window->setVisible(true);
|
||||||
|
window->showNormal();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m_prevAppState = ev->applicationState();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return QObject::eventFilter(obj, event);
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
#include "DOtherSide/StatusEvents/StatusOSThemeEvent.h"
|
||||||
|
|
||||||
|
#include <QQuickWindow>
|
||||||
|
|
||||||
|
StatusOSThemeEvent::StatusOSThemeEvent(DosQQmlApplicationEngine* vptr, QObject* parent)
|
||||||
|
: QObject(parent)
|
||||||
|
{
|
||||||
|
m_engine = static_cast<QQmlApplicationEngine*>(vptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool StatusOSThemeEvent::eventFilter(QObject *obj, QEvent *event)
|
||||||
|
{
|
||||||
|
if (event->type() == QEvent::PaletteChange ||
|
||||||
|
event->type() == QEvent::ApplicationPaletteChange)
|
||||||
|
{
|
||||||
|
QObject* topLevelObj = m_engine->rootObjects().value(0);
|
||||||
|
if(topLevelObj && topLevelObj->objectName() == "mainWindow")
|
||||||
|
{
|
||||||
|
QQuickWindow* window = qobject_cast<QQuickWindow *>(topLevelObj);
|
||||||
|
if(window)
|
||||||
|
{
|
||||||
|
QMetaObject::invokeMethod(window, "changeThemeFromOutside");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return QObject::eventFilter(obj, event);
|
||||||
|
}
|
Loading…
Reference in New Issue