From 8530b851b25d411f7db0499b7df8b5e8fdf95876 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Fri, 17 May 2019 11:26:35 +0200 Subject: 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 --- src/compositor/extensions/qwaylandxdgshellv5.cpp | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) (limited to 'src/compositor/extensions/qwaylandxdgshellv5.cpp') 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 +std::reverse_iterator make_reverse(Iterator it) +{ + return std::reverse_iterator(std::move(it)); +} + void QWaylandXdgShellV5::closeAllPopups() { Q_D(QWaylandXdgShellV5); - Q_FOREACH (struct wl_client *client, d->m_xdgPopups.keys()) { - QList 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(); } } -- cgit v1.2.3