[*] Forward port aus Qt5.15.x modifications (fa1e8e30-cdb97232)

[*] Make menu/setmenu visible again

Change-Id: I67d57ea65edab26154fc92705cd34863c996eced
This commit is contained in:
Reece Wilson 2023-11-23 22:41:14 +00:00
parent 21b26bac26
commit a050d42ef2
11 changed files with 90 additions and 21 deletions

View File

@ -147,6 +147,7 @@ qt_internal_add_module(Core
io/qzipreader_p.h io/qzipwriter_p.h io/qzip.cpp io/qzipreader_p.h io/qzipwriter_p.h io/qzip.cpp
kernel/qabstracteventdispatcher.cpp kernel/qabstracteventdispatcher.h kernel/qabstracteventdispatcher_p.h kernel/qabstracteventdispatcher.cpp kernel/qabstracteventdispatcher.h kernel/qabstracteventdispatcher_p.h
kernel/qabstractnativeeventfilter.cpp kernel/qabstractnativeeventfilter.h kernel/qabstractnativeeventfilter.cpp kernel/qabstractnativeeventfilter.h
kernel/qthreadawareeventdispatcher.cpp
kernel/qapplicationstatic.h kernel/qapplicationstatic.h
kernel/qassociativeiterable.cpp kernel/qassociativeiterable.h kernel/qassociativeiterable.cpp kernel/qassociativeiterable.h
kernel/qbasictimer.cpp kernel/qbasictimer.h kernel/qbasictimer.cpp kernel/qbasictimer.h

View File

@ -4,6 +4,7 @@
#include "qbasictimer.h" #include "qbasictimer.h"
#include "qabstracteventdispatcher.h" #include "qabstracteventdispatcher.h"
#include "qabstracteventdispatcher_p.h" #include "qabstracteventdispatcher_p.h"
#include "qthreadawareeventdispatcher_i.hpp"
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
@ -158,10 +159,15 @@ void QBasicTimer::start(std::chrono::milliseconds duration, Qt::TimerType timerT
qWarning("QBasicTimer::start: QBasicTimer can only be used with threads started with QThread"); qWarning("QBasicTimer::start: QBasicTimer can only be used with threads started with QThread");
return; return;
} }
if (Q_UNLIKELY(obj && obj->thread() != eventDispatcher->thread())) {
qWarning("QBasicTimer::start: Timers cannot be started from another thread"); if (!gGlobalEventDispatcher)
return; {
if (Q_UNLIKELY(obj && obj->thread() != eventDispatcher->thread())) {
qWarning("QBasicTimer::start: Timers cannot be started from another thread");
return;
}
} }
stop(); stop();
if (obj) if (obj)
id = eventDispatcher->registerTimer(duration.count(), timerType, obj); id = eventDispatcher->registerTimer(duration.count(), timerType, obj);
@ -176,10 +182,22 @@ void QBasicTimer::stop()
{ {
if (id) { if (id) {
QAbstractEventDispatcher *eventDispatcher = QAbstractEventDispatcher::instance(); QAbstractEventDispatcher *eventDispatcher = QAbstractEventDispatcher::instance();
if (eventDispatcher && !eventDispatcher->unregisterTimer(id)) {
qWarning("QBasicTimer::stop: Failed. Possibly trying to stop from a different thread"); if (!gGlobalEventDispatcher)
return; {
if (eventDispatcher && !eventDispatcher->unregisterTimer(id)) {
qWarning("QBasicTimer::stop: Failed. Possibly trying to stop from a different thread");
return;
}
} }
else
{
if (!gGlobalEventDispatcher->unregisterTimer(id)) {
qWarning("QBasicTimer::stop: Failed. Possibly trying to stop from a different thread");
return;
}
}
QAbstractEventDispatcherPrivate::releaseTimerId(id); QAbstractEventDispatcherPrivate::releaseTimerId(id);
} }
id = 0; id = 0;

View File

@ -109,6 +109,8 @@
#include <memory> #include <memory>
#include <string> #include <string>
#include "qthreadawareeventdispatcher_i.hpp"
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
using namespace Qt::StringLiterals; using namespace Qt::StringLiterals;
@ -506,6 +508,11 @@ void QCoreApplicationPrivate::cleanupThreadData()
void QCoreApplicationPrivate::createEventDispatcher() void QCoreApplicationPrivate::createEventDispatcher()
{ {
Q_Q(QCoreApplication); Q_Q(QCoreApplication);
if (gGlobalEventDispatcher) {
return;
}
QThreadData *data = QThreadData::current(); QThreadData *data = QThreadData::current();
Q_ASSERT(!data->hasEventDispatcher()); Q_ASSERT(!data->hasEventDispatcher());
eventDispatcher = data->createEventDispatcher(); eventDispatcher = data->createEventDispatcher();
@ -899,15 +906,19 @@ void Q_TRACE_INSTRUMENT(qtcore) QCoreApplicationPrivate::init()
Q_ASSERT(!eventDispatcher); Q_ASSERT(!eventDispatcher);
auto thisThreadData = threadData.loadRelaxed(); auto thisThreadData = threadData.loadRelaxed();
eventDispatcher = thisThreadData->eventDispatcher.loadRelaxed(); eventDispatcher = thisThreadData->eventDispatcher.loadRelaxed();
if (gGlobalEventDispatcher) {
eventDispatcher = gGlobalEventDispatcher;
} else {
// otherwise we create one
if (!eventDispatcher)
createEventDispatcher();
Q_ASSERT(eventDispatcher);
// otherwise we create one if (!eventDispatcher->parent()) {
if (!eventDispatcher) eventDispatcher->moveToThread(thisThreadData->thread.loadAcquire());
createEventDispatcher(); eventDispatcher->setParent(q);
Q_ASSERT(eventDispatcher); }
if (!eventDispatcher->parent()) {
eventDispatcher->moveToThread(thisThreadData->thread.loadAcquire());
eventDispatcher->setParent(q);
} }
thisThreadData->eventDispatcher = eventDispatcher; thisThreadData->eventDispatcher = eventDispatcher;

View File

@ -0,0 +1,3 @@
#include "qthreadawareeventdispatcher_i.hpp"
SECRET_PLATFORM_EXPORT QAbstractEventDispatcher *gGlobalEventDispatcher = {};

View File

@ -0,0 +1,8 @@
#pragma once
#if !defined(SECRET_PLATFORM_EXPORT)
#define SECRET_PLATFORM_EXPORT __declspec(dllexport)
#endif
extern SECRET_PLATFORM_EXPORT QAbstractEventDispatcher *gGlobalEventDispatcher;

View File

@ -14,6 +14,8 @@
#include "qthread_p.h" #include "qthread_p.h"
#include "private/qcoreapplication_p.h" #include "private/qcoreapplication_p.h"
#include "../kernel/qthreadawareeventdispatcher_i.hpp"
#include <limits> #include <limits>
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
@ -111,7 +113,9 @@ void QThreadData::deref()
QAbstractEventDispatcher *QThreadData::createEventDispatcher() QAbstractEventDispatcher *QThreadData::createEventDispatcher()
{ {
QAbstractEventDispatcher *ed = QThreadPrivate::createEventDispatcher(this); QAbstractEventDispatcher *ed = gGlobalEventDispatcher ?
gGlobalEventDispatcher :
QThreadPrivate::createEventDispatcher(this);
eventDispatcher.storeRelease(ed); eventDispatcher.storeRelease(ed);
return ed; return ed;
} }

View File

@ -19,6 +19,8 @@
#endif // _MT #endif // _MT
#include <process.h> #include <process.h>
#include "../kernel/qthreadawareeventdispatcher_i.hpp"
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
#if QT_CONFIG(thread) #if QT_CONFIG(thread)
@ -327,7 +329,12 @@ void QThreadPrivate::finish(void *arg, bool lockAnyway) noexcept
if (lockAnyway) if (lockAnyway)
locker.unlock(); locker.unlock();
eventDispatcher->closingDown(); eventDispatcher->closingDown();
delete eventDispatcher;
if (gGlobalEventDispatcher != eventDispatcher)
{
delete eventDispatcher;
}
if (lockAnyway) if (lockAnyway)
locker.relock(); locker.relock();
} }

View File

@ -335,6 +335,16 @@ void QAction::setShortcuts(QKeySequence::StandardKey key)
setShortcuts(list); setShortcuts(list);
} }
QMenu *QAction::menu2() const
{
return (QMenu *)menuObject();
}
void QAction::setMenu2(QMenu *m)
{
setMenuObject((QObject *)m);
}
/*! /*!
Returns the primary shortcut. Returns the primary shortcut.

View File

@ -182,18 +182,22 @@ public:
QMenu *menu() const; QMenu *menu() const;
void setMenu(QMenu *menu); void setMenu(QMenu *menu);
#else #else
template<typename T = QMenu*> template<typename T = QMenu *>
T menu() const T menu() const
{ {
return qobject_cast<T>(menuObject()); return qobject_cast<T>(menuObject());
} }
template<typename T = QMenu*> template<typename T = QMenu *>
void setMenu(T m) void setMenu(T m)
{ {
setMenuObject(m); setMenuObject(m);
} }
#endif #endif
QMenu *menu2() const;
void setMenu2(QMenu *m);
void setIconVisibleInMenu(bool visible); void setIconVisibleInMenu(bool visible);
bool isIconVisibleInMenu() const; bool isIconVisibleInMenu() const;

View File

@ -3696,8 +3696,7 @@ void QGuiApplicationPrivate::maybeLastWindowClosed()
if (!lastWindowClosed()) if (!lastWindowClosed())
return; return;
if (in_exec) emit q_func()->lastWindowClosed();
emit q_func()->lastWindowClosed();
if (quitOnLastWindowClosed && canQuitAutomatically()) if (quitOnLastWindowClosed && canQuitAutomatically())
quitAutomatically(); quitAutomatically();

View File

@ -975,7 +975,11 @@ void QLayout::update()
if (layout->d_func()->topLevel) { if (layout->d_func()->topLevel) {
Q_ASSERT(layout->parent()->isWidgetType()); Q_ASSERT(layout->parent()->isWidgetType());
QWidget *mw = static_cast<QWidget*>(layout->parent()); QWidget *mw = static_cast<QWidget*>(layout->parent());
QCoreApplication::postEvent(mw, new QEvent(QEvent::LayoutRequest)); if (mw) { /*we always validate layout later, implying it can be null. why the fuck were the Qt devs copying the [~volatile~] parent multiple times and using it without a check?
(ok, not volatile - it's usually single threaded, but still two instances of encapsulated access.) */
Q_ASSERT(mw->isWidgetType());
QCoreApplication::postEvent(mw, new QEvent(QEvent::LayoutRequest));
}
break; break;
} }
layout = static_cast<QLayout*>(layout->parent()); layout = static_cast<QLayout*>(layout->parent());