diff --git a/src/ui/manager.cpp b/src/ui/manager.cpp index b10a8eba5..7b1206a61 100644 --- a/src/ui/manager.cpp +++ b/src/ui/manager.cpp @@ -639,7 +639,10 @@ void Manager::handleMouseDown(Display* display, PointerType pointerType, const float pressure) { - handleWindowZOrder(); + // Returns false in case that we click another Display (os::Window) + // that is not the current running top-most foreground window. + if (!handleWindowZOrder()) + return; enqueueMessage( newMouseMessage( @@ -730,45 +733,49 @@ void Manager::handleTouchMagnify(Display* display, // window that aren't the desktop). // // TODO code similar to Display::handleWindowZOrder() -void Manager::handleWindowZOrder() +bool Manager::handleWindowZOrder() { if (capture_widget || !mouse_widget) - return; + return true; // The clicked window Window* window = mouse_widget->window(); - Manager* win_manager = (window ? window->manager(): nullptr); + Window* topWindow = getTopWindow(); if ((window) && - // We cannot change Z-order of desktop windows - (!window->isDesktop()) && - // We cannot change Z order of foreground windows because a - // foreground window can launch other background windows - // which should be kept on top of the foreground one. - (!window->isForeground()) && - // If the window is not already the top window of the manager. - (window != win_manager->getTopWindow())) { + // We cannot change Z-order of desktop windows + (!window->isDesktop()) && + // We cannot change Z order of foreground windows because a + // foreground window can launch other background windows + // which should be kept on top of the foreground one. + (!window->isForeground()) && + // If the window is not already the top window of the manager. + (window != topWindow)) { + // If there is already a top foreground window, cancel the z-order change + if (topWindow && topWindow->isForeground()) + return false; + base::ScopedValue scoped(m_lockedWindow, window); window->display()->handleWindowZOrder(window); // Put it in the top of the list - win_manager->removeChild(window); + removeChild(window); if (window->isOnTop()) - win_manager->insertChild(0, window); + insertChild(0, window); else { - int pos = (int)win_manager->children().size(); + int pos = (int)children().size(); - for (auto it=win_manager->children().rbegin(), - end=win_manager->children().rend(); + for (auto it=children().rbegin(), + end=children().rend(); it != end; ++it) { if (static_cast(*it)->isOnTop()) break; --pos; } - win_manager->insertChild(pos, window); + insertChild(pos, window); } if (!window->ownDisplay()) @@ -777,6 +784,7 @@ void Manager::handleWindowZOrder() // Put the focus setFocus(mouse_widget); + return true; } // If display is nullptr, mousePos is in screen coordinates, if not, diff --git a/src/ui/manager.h b/src/ui/manager.h index 5c0e4ced7..022604789 100644 --- a/src/ui/manager.h +++ b/src/ui/manager.h @@ -1,5 +1,5 @@ // Aseprite UI Library -// Copyright (C) 2018-2022 Igara Studio S.A. +// Copyright (C) 2018-2023 Igara Studio S.A. // Copyright (C) 2001-2017 David Capello // // This file is released under the terms of the MIT license. @@ -152,7 +152,7 @@ namespace ui { const gfx::Point& mousePos, const KeyModifiers modifiers, const double magnification); - void handleWindowZOrder(); + bool handleWindowZOrder(); void updateMouseWidgets(const gfx::Point& mousePos, Display* display);