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/DosQAbstractItemModel.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/DOtherSideSingleInstance.h
|
||||
src/DOtherSide.cpp
|
||||
|
@ -31,7 +32,8 @@ macro(add_target name type)
|
|||
src/DosQObjectImpl.cpp
|
||||
src/DosQAbstractItemModel.cpp
|
||||
src/DosQQuickImageProvider.cpp
|
||||
src/DosDockClicker.cpp
|
||||
src/StatusEvents/StatusDockShowAppEvent.cpp
|
||||
src/StatusEvents/StatusOSThemeEvent.cpp
|
||||
src/DOtherSideStatusWindow.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_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_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
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -98,6 +98,9 @@ typedef void DosPixmap;
|
|||
/// A pointer to SingleInstance
|
||||
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
|
||||
/// \param id Image source id
|
||||
/// \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/DosQDeclarative.h"
|
||||
#include "DOtherSide/DosQQuickImageProvider.h"
|
||||
#include "DOtherSide/DosDockClicker.h"
|
||||
#include "DOtherSide/DOtherSideStatusWindow.h"
|
||||
#include "DOtherSide/DOtherSideSingleInstance.h"
|
||||
|
||||
#include "DOtherSide/StatusEvents/StatusDockShowAppEvent.h"
|
||||
#include "DOtherSide/StatusEvents/StatusOSThemeEvent.h"
|
||||
|
||||
namespace {
|
||||
|
||||
void register_meta_types()
|
||||
|
@ -155,7 +157,8 @@ void dos_qguiapplication_exec()
|
|||
|
||||
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)
|
||||
|
@ -163,10 +166,10 @@ void dos_qguiapplication_icon(const char *filename)
|
|||
qGuiApp->setWindowIcon(QIcon(filename));
|
||||
}
|
||||
|
||||
void dos_qguiapplication_installEventFilter(::DosQQmlApplicationEngine *vptr)
|
||||
void dos_qguiapplication_installEventFilter(::DosStatusEventObject* vptr)
|
||||
{
|
||||
DockClicker *dockClicker = new DockClicker(vptr);
|
||||
qGuiApp->installEventFilter(dockClicker);
|
||||
auto qobject = static_cast<QObject*>(vptr);
|
||||
qGuiApp->installEventFilter(qobject);
|
||||
}
|
||||
|
||||
void dos_qapplication_create()
|
||||
|
@ -196,13 +199,14 @@ void dos_qapplication_icon(const char *filename)
|
|||
|
||||
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);
|
||||
qApp->installEventFilter(dockClicker);
|
||||
auto qobject = static_cast<QObject*>(vptr);
|
||||
qApp->installEventFilter(qobject);
|
||||
}
|
||||
|
||||
::DosQQmlApplicationEngine *dos_qqmlapplicationengine_create()
|
||||
|
@ -1313,3 +1317,21 @@ bool dos_singleinstance_isfirst(DosSingleInstance *vptr)
|
|||
}
|
||||
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