45
45
#include < chrono>
46
46
#include < QObject>
47
47
#include < QTimerEvent>
48
+ #include < QApplication>
48
49
49
50
namespace promise {
50
51
@@ -75,28 +76,31 @@ class PromiseEventFilter : public QObject {
75
76
protected:
76
77
bool eventFilter (QObject *object, QEvent *event) {
77
78
std::pair<QObject *, QEvent::Type> key = { object, event->type () };
78
- Listeners::iterator itr = listeners_.find (key);
79
- if (itr != listeners_.end ()) {
80
- return itr->second (object, event);
79
+
80
+ // may not safe if one handler is removed by other
81
+ std::list<Listeners::iterator> itrs;
82
+ for (Listeners::iterator itr = listeners_.lower_bound (key);
83
+ itr != listeners_.end () && key == itr->first ; ++itr) {
84
+ itrs.push_back (itr);
85
+ }
86
+ for (Listeners::iterator itr: itrs) {
87
+ itr->second (object, event);
81
88
}
82
89
83
90
if (event->type () == QEvent::Destroy) {
84
- return removeObjectFilters (object);
91
+ removeObjectFilters (object);
85
92
}
86
93
87
- return false ;
94
+ return QObject::eventFilter (object, event) ;
88
95
}
89
96
90
97
bool removeObjectFilters (QObject *object) {
91
98
std::pair<QObject *, QEvent::Type> key = { object, QEvent::None };
92
99
93
- std::list<Listeners::iterator> deletes;
94
-
95
-
100
+ // checked one by one for safety (others may be removed)
96
101
while (true ) {
97
102
Listeners::iterator itr = listeners_.lower_bound (key);
98
103
if (itr != listeners_.end () && itr->first .first == object) {
99
- // one by one for safety
100
104
itr->second (object, nullptr );
101
105
}
102
106
else {
@@ -112,20 +116,34 @@ class PromiseEventFilter : public QObject {
112
116
113
117
// Wait event will wait the event for only once
114
118
inline Defer waitEvent (QObject *object,
115
- QEvent::Type eventType) {
119
+ QEvent::Type eventType,
120
+ bool callSysHandler = false ) {
116
121
Defer promise = newPromise ();
117
122
123
+ std::shared_ptr<bool > disableFilter = std::make_shared<bool >(false );
118
124
auto listener = PromiseEventFilter::getSingleInstance ().addEventListener (
119
- object, eventType, [promise](QObject *object, QEvent *event) {
125
+ object, eventType, [promise, callSysHandler, disableFilter ](QObject *object, QEvent *event) {
120
126
(void )object;
121
- if (event == nullptr )
127
+ if (event == nullptr ) {
122
128
promise->reject ();
129
+ return false ;
130
+ }
131
+ // The next then function will be call immediately
132
+ // Be care that do not use event in the next event loop
133
+ else if (*disableFilter) {
134
+ return false ;
135
+ }
136
+ else if (callSysHandler) {
137
+ *disableFilter = true ;
138
+ QApplication::sendEvent (object, event);
139
+ *disableFilter = false ;
140
+ promise->resolve (event);
141
+ return true ;
142
+ }
123
143
else {
124
- // The next then function will be call immediately
125
- // Be care that do not use event in the next event loop
126
144
promise->resolve (event);
145
+ return false ;
127
146
}
128
- return false ;
129
147
}
130
148
);
131
149
0 commit comments