diff options
author | Marc Mutz <marc.mutz@kdab.com> | 2019-05-17 11:26:35 +0200 |
---|---|---|
committer | Marc Mutz <marc.mutz@kdab.com> | 2019-06-05 09:51:13 +0000 |
commit | 8530b851b25d411f7db0499b7df8b5e8fdf95876 (patch) | |
tree | bb6a7d67f2685180e70b987d5f32db8147b6f47e /src/compositor | |
parent | 280d0e557eabe9410632edf32ed46e712535c45b (diff) |
QWaylandXdgShellV5: optimize closeAllPopups()
The code iterated over QMultiMap::keys(), calling QMultiMap::value()
for each key, reversed the list returned by values() and then iterated
over it to call sendPopupDone().
The QMultiMap is keyed on a pointer type, so the order of keys is
unspecified. We can therefore simply iterate backwards over the
QMultiMap, and just call our function that way. The order in which the
keys are visited is reversed, but since they are unordered, this does
not change behavior. Since we iterate backwards, we will visit popups
for the same key in the same order the old code did.
Except we don't create 1 + N new containers in doing so.
Only problem: well-maintained QMultiMap doesn't have rbegin()/rend(),
yet, so roll our own std::make_reverse_iterator for easier porting
later.
Change-Id: Ibec35cb4262dd5bb19c74821e85baa956f67dd05
Reviewed-by: Johan Helsing <johan.helsing@qt.io>
Diffstat (limited to 'src/compositor')
-rw-r--r-- | src/compositor/extensions/qwaylandxdgshellv5.cpp | 16 |
1 files changed, 10 insertions, 6 deletions
diff --git a/src/compositor/extensions/qwaylandxdgshellv5.cpp b/src/compositor/extensions/qwaylandxdgshellv5.cpp index eebfab6d6..a40c21682 100644 --- a/src/compositor/extensions/qwaylandxdgshellv5.cpp +++ b/src/compositor/extensions/qwaylandxdgshellv5.cpp @@ -627,15 +627,19 @@ uint QWaylandXdgShellV5::ping(QWaylandClient *client) return serial; } +// ### remove once QMap has rbegin()/rend() +template <typename Iterator> +std::reverse_iterator<Iterator> make_reverse(Iterator it) +{ + return std::reverse_iterator<Iterator>(std::move(it)); +} + void QWaylandXdgShellV5::closeAllPopups() { Q_D(QWaylandXdgShellV5); - Q_FOREACH (struct wl_client *client, d->m_xdgPopups.keys()) { - QList<QWaylandXdgPopupV5 *> popups = d->m_xdgPopups.values(client); - std::reverse(popups.begin(), popups.end()); - Q_FOREACH (QWaylandXdgPopupV5 *currentTopmostPopup, popups) { - currentTopmostPopup->sendPopupDone(); - } + // Close pop-ups from top-most to bottom-most, lest we get protocol errors: + for (auto rit = make_reverse(d->m_xdgPopups.end()), rend = make_reverse(d->m_xdgPopups.begin()); rit != rend; ++rit) { + (*rit)->sendPopupDone(); } } |