Fix bug losing the ui::DIRTY flag from the ui::Manager after closing a fullscreen ui::Window

This commit is contained in:
David Capello 2018-12-04 17:44:21 -03:00
parent 0a179acc90
commit f6a2090ed9
2 changed files with 42 additions and 9 deletions

View File

@ -1,4 +1,5 @@
// Aseprite // Aseprite
// Copyright (C) 2018 Igara Studio S.A.
// Copyright (C) 2001-2018 David Capello // Copyright (C) 2001-2018 David Capello
// //
// This program is distributed under the terms of // This program is distributed under the terms of
@ -10,7 +11,6 @@
#include "ui/ui.h" #include "ui/ui.h"
#include "app/app.h"
#include "app/commands/command.h" #include "app/commands/command.h"
#include "app/commands/commands.h" #include "app/commands/commands.h"
#include "app/context.h" #include "app/context.h"
@ -286,7 +286,12 @@ void FullscreenPreviewCommand::onExecute(Context* context)
PreviewWindow window(context, editor); PreviewWindow window(context, editor);
window.openWindowInForeground(); window.openWindowInForeground();
app_refresh_screen(); // Check that the full screen invalidation code is working
// correctly. This check is just in case that some regression is
// introduced in ui::Manager() that doesn't handle correctly the
// invalidation of the manager when it's fully covered by the closed
// window (desktop windows, like PreviewWindow, match this case).
ASSERT(editor->manager()->hasFlags(DIRTY));
} }
Command* CommandFactory::createFullscreenPreviewCommand() Command* CommandFactory::createFullscreenPreviewCommand()

View File

@ -45,6 +45,20 @@
namespace ui { namespace ui {
namespace {
// The redraw state is used to avoid drawing the manager when a window
// has been just closed by the user, so we delay the redrawing (the
// kPaintMessages generation) for the next generateMessages() round.
enum class RedrawState {
Normal,
AWindowHasJustBeenClosed,
RedrawDelayed,
};
RedrawState redrawState = RedrawState::Normal;
} // anonymous namespace
#define ACCEPT_FOCUS(widget) \ #define ACCEPT_FOCUS(widget) \
((((widget)->flags() & (FOCUS_STOP | \ ((((widget)->flags() & (FOCUS_STOP | \
DISABLED | \ DISABLED | \
@ -636,14 +650,26 @@ void Manager::dispatchMessages()
// might change the state of widgets, etc. In case pumpQueue() // might change the state of widgets, etc. In case pumpQueue()
// returns a number greater than 0, it means that we've processed // returns a number greater than 0, it means that we've processed
// some messages, so we've to redraw the screen. // some messages, so we've to redraw the screen.
if (pumpQueue() > 0) { if (pumpQueue() > 0 || redrawState == RedrawState::RedrawDelayed) {
// Generate and send just kPaintMessages with the latest UI state. // If a window has just been closed with Manager::_closeWindow()
flushRedraw(); // after processing messages, we'll wait the next event generation
pumpQueue(); // to process painting events (so the manager doesn't lost the
} // DIRTY flag right now).
if (redrawState == RedrawState::AWindowHasJustBeenClosed) {
redrawState = RedrawState::RedrawDelayed;
}
else {
if (redrawState == RedrawState::RedrawDelayed)
redrawState = RedrawState::Normal;
// Flip the back-buffer to the real display. // Generate and send just kPaintMessages with the latest UI state.
flipDisplay(); flushRedraw();
pumpQueue();
// Flip the back-buffer to the real display.
flipDisplay();
}
}
} }
void Manager::addToGarbage(Widget* widget) void Manager::addToGarbage(Widget* widget)
@ -1153,6 +1179,8 @@ void Manager::_closeWindow(Window* window, bool redraw_background)
Widget* widget = pick(ui::get_mouse_position()); Widget* widget = pick(ui::get_mouse_position());
if (widget) if (widget)
setMouse(widget); setMouse(widget);
redrawState = RedrawState::AWindowHasJustBeenClosed;
} }
bool Manager::onProcessMessage(Message* msg) bool Manager::onProcessMessage(Message* msg)