Update display immediately after and undo/redo command is executed from the native macOS menu (fix #2069)

Replaced ui::kFunctionMessage with os::Event::Callback.
This commit is contained in:
David Capello 2019-05-27 22:51:22 -03:00
parent df741c246b
commit bcf6899793
7 changed files with 67 additions and 80 deletions

2
laf

@ -1 +1 @@
Subproject commit f81220824324b75ec52ad7aae3d23d0610bd8144 Subproject commit 5afdc83f2ba9622aa37e520ad6b2a605d46022fb

View File

@ -327,9 +327,9 @@ void Manager::generateSetCursorMessage(const gfx::Point& mousePos,
set_mouse_cursor(kArrowCursor); set_mouse_cursor(kArrowCursor);
} }
static MouseButtons mouse_buttons_from_os_to_ui(const os::Event& sheEvent) static MouseButtons mouse_buttons_from_os_to_ui(const os::Event& osEvent)
{ {
switch (sheEvent.button()) { switch (osEvent.button()) {
case os::Event::LeftButton: return kButtonLeft; break; case os::Event::LeftButton: return kButtonLeft; break;
case os::Event::RightButton: return kButtonRight; break; case os::Event::RightButton: return kButtonRight; break;
case os::Event::MiddleButton: return kButtonMiddle; break; case os::Event::MiddleButton: return kButtonMiddle; break;
@ -347,8 +347,8 @@ void Manager::generateMessagesFromOSEvents()
os::Event lastMouseMoveEvent; os::Event lastMouseMoveEvent;
// Events from "she" layer. // Events from laf-os
os::Event sheEvent; os::Event osEvent;
for (;;) { for (;;) {
// TODO Add timers to laf::os library so we can wait for then in // TODO Add timers to laf::os library so we can wait for then in
// the OS message loop. // the OS message loop.
@ -370,11 +370,11 @@ void Manager::generateMessagesFromOSEvents()
} }
#endif #endif
m_eventQueue->getEvent(sheEvent, canWait); m_eventQueue->getEvent(osEvent, canWait);
if (sheEvent.type() == os::Event::None) if (osEvent.type() == os::Event::None)
break; break;
switch (sheEvent.type()) { switch (osEvent.type()) {
case os::Event::CloseDisplay: { case os::Event::CloseDisplay: {
Message* msg = new Message(kCloseDisplayMessage); Message* msg = new Message(kCloseDisplayMessage);
@ -393,7 +393,7 @@ void Manager::generateMessagesFromOSEvents()
} }
case os::Event::DropFiles: { case os::Event::DropFiles: {
Message* msg = new DropFilesMessage(sheEvent.files()); Message* msg = new DropFilesMessage(osEvent.files());
msg->setRecipient(this); msg->setRecipient(this);
enqueueMessage(msg); enqueueMessage(msg);
break; break;
@ -402,15 +402,15 @@ void Manager::generateMessagesFromOSEvents()
case os::Event::KeyDown: case os::Event::KeyDown:
case os::Event::KeyUp: { case os::Event::KeyUp: {
Message* msg = new KeyMessage( Message* msg = new KeyMessage(
(sheEvent.type() == os::Event::KeyDown ? (osEvent.type() == os::Event::KeyDown ?
kKeyDownMessage: kKeyDownMessage:
kKeyUpMessage), kKeyUpMessage),
sheEvent.scancode(), osEvent.scancode(),
sheEvent.modifiers(), osEvent.modifiers(),
sheEvent.unicodeChar(), osEvent.unicodeChar(),
sheEvent.repeat()); osEvent.repeat());
if (sheEvent.isDeadKey()) if (osEvent.isDeadKey())
static_cast<KeyMessage*>(msg)->setDeadKey(true); static_cast<KeyMessage*>(msg)->setDeadKey(true);
broadcastKeyMsg(msg); broadcastKeyMsg(msg);
@ -419,9 +419,9 @@ void Manager::generateMessagesFromOSEvents()
} }
case os::Event::MouseEnter: { case os::Event::MouseEnter: {
_internal_set_mouse_position(sheEvent.position()); _internal_set_mouse_position(osEvent.position());
set_mouse_cursor(kArrowCursor); set_mouse_cursor(kArrowCursor);
lastMouseMoveEvent = sheEvent; lastMouseMoveEvent = osEvent;
break; break;
} }
@ -438,67 +438,73 @@ void Manager::generateMessagesFromOSEvents()
} }
case os::Event::MouseMove: { case os::Event::MouseMove: {
_internal_set_mouse_position(sheEvent.position()); _internal_set_mouse_position(osEvent.position());
handleMouseMove( handleMouseMove(
sheEvent.position(), osEvent.position(),
m_mouseButtons, m_mouseButtons,
sheEvent.modifiers(), osEvent.modifiers(),
sheEvent.pointerType()); osEvent.pointerType());
lastMouseMoveEvent = sheEvent; lastMouseMoveEvent = osEvent;
break; break;
} }
case os::Event::MouseDown: { case os::Event::MouseDown: {
MouseButtons pressedButton = mouse_buttons_from_os_to_ui(sheEvent); MouseButtons pressedButton = mouse_buttons_from_os_to_ui(osEvent);
m_mouseButtons = (MouseButtons)((int)m_mouseButtons | (int)pressedButton); m_mouseButtons = (MouseButtons)((int)m_mouseButtons | (int)pressedButton);
_internal_set_mouse_buttons(m_mouseButtons); _internal_set_mouse_buttons(m_mouseButtons);
handleMouseDown( handleMouseDown(
sheEvent.position(), osEvent.position(),
pressedButton, pressedButton,
sheEvent.modifiers(), osEvent.modifiers(),
sheEvent.pointerType()); osEvent.pointerType());
break; break;
} }
case os::Event::MouseUp: { case os::Event::MouseUp: {
MouseButtons releasedButton = mouse_buttons_from_os_to_ui(sheEvent); MouseButtons releasedButton = mouse_buttons_from_os_to_ui(osEvent);
m_mouseButtons = (MouseButtons)((int)m_mouseButtons & ~(int)releasedButton); m_mouseButtons = (MouseButtons)((int)m_mouseButtons & ~(int)releasedButton);
_internal_set_mouse_buttons(m_mouseButtons); _internal_set_mouse_buttons(m_mouseButtons);
handleMouseUp( handleMouseUp(
sheEvent.position(), osEvent.position(),
releasedButton, releasedButton,
sheEvent.modifiers(), osEvent.modifiers(),
sheEvent.pointerType()); osEvent.pointerType());
break; break;
} }
case os::Event::MouseDoubleClick: { case os::Event::MouseDoubleClick: {
MouseButtons clickedButton = mouse_buttons_from_os_to_ui(sheEvent); MouseButtons clickedButton = mouse_buttons_from_os_to_ui(osEvent);
handleMouseDoubleClick( handleMouseDoubleClick(
sheEvent.position(), osEvent.position(),
clickedButton, clickedButton,
sheEvent.modifiers(), osEvent.modifiers(),
sheEvent.pointerType()); osEvent.pointerType());
break; break;
} }
case os::Event::MouseWheel: { case os::Event::MouseWheel: {
handleMouseWheel(sheEvent.position(), m_mouseButtons, handleMouseWheel(osEvent.position(), m_mouseButtons,
sheEvent.modifiers(), osEvent.modifiers(),
sheEvent.pointerType(), osEvent.pointerType(),
sheEvent.wheelDelta(), osEvent.wheelDelta(),
sheEvent.preciseWheel()); osEvent.preciseWheel());
break; break;
} }
case os::Event::TouchMagnify: { case os::Event::TouchMagnify: {
_internal_set_mouse_position(sheEvent.position()); _internal_set_mouse_position(osEvent.position());
handleTouchMagnify(sheEvent.position(), handleTouchMagnify(osEvent.position(),
sheEvent.modifiers(), osEvent.modifiers(),
sheEvent.magnification()); osEvent.magnification());
break;
}
case os::Event::Callback: {
// Call from the UI thread
osEvent.execCallback();
break; break;
} }
@ -507,10 +513,10 @@ void Manager::generateMessagesFromOSEvents()
// Generate just one kSetCursorMessage for the last mouse position // Generate just one kSetCursorMessage for the last mouse position
if (lastMouseMoveEvent.type() != os::Event::None) { if (lastMouseMoveEvent.type() != os::Event::None) {
sheEvent = lastMouseMoveEvent; osEvent = lastMouseMoveEvent;
generateSetCursorMessage(sheEvent.position(), generateSetCursorMessage(osEvent.position(),
sheEvent.modifiers(), osEvent.modifiers(),
sheEvent.pointerType()); osEvent.pointerType());
} }
} }
@ -1433,8 +1439,6 @@ bool Manager::sendMessageToWidget(Message* msg, Widget* widget)
#ifdef REPORT_EVENTS #ifdef REPORT_EVENTS
{ {
static const char* msg_name[] = { static const char* msg_name[] = {
"kFunctionMessage",
"kOpenMessage", "kOpenMessage",
"kCloseMessage", "kCloseMessage",
"kCloseDisplayMessage", "kCloseDisplayMessage",
@ -1459,7 +1463,7 @@ bool Manager::sendMessageToWidget(Message* msg, Widget* widget)
"kMouseWheelMessage", "kMouseWheelMessage",
"kTouchMagnifyMessage", "kTouchMagnifyMessage",
}; };
static_assert(kFunctionMessage == 0 && static_assert(kOpenMessage == 0 &&
kTouchMagnifyMessage == sizeof(msg_name)/sizeof(const char*)-1, kTouchMagnifyMessage == sizeof(msg_name)/sizeof(const char*)-1,
"MessageType enum has changed"); "MessageType enum has changed");
const char* string = const char* string =

View File

@ -1,5 +1,5 @@
// Aseprite UI Library // Aseprite UI Library
// Copyright (C) 2018 Igara Studio S.A. // Copyright (C) 2018-2019 Igara Studio S.A.
// Copyright (C) 2001-2018 David Capello // Copyright (C) 2001-2018 David Capello
// //
// This file is released under the terms of the MIT license. // This file is released under the terms of the MIT license.
@ -18,8 +18,6 @@
#include "ui/mouse_buttons.h" #include "ui/mouse_buttons.h"
#include "ui/pointer_type.h" #include "ui/pointer_type.h"
#include <functional>
namespace ui { namespace ui {
class Timer; class Timer;
@ -79,16 +77,6 @@ namespace ui {
KeyModifiers m_modifiers; // Key modifiers pressed when message was created KeyModifiers m_modifiers; // Key modifiers pressed when message was created
}; };
class FunctionMessage : public Message {
public:
FunctionMessage(std::function<void()>&& f)
: Message(kFunctionMessage),
m_f(std::move(f)) { }
void call() { m_f(); }
private:
std::function<void()> m_f;
};
class KeyMessage : public Message { class KeyMessage : public Message {
public: public:
KeyMessage(MessageType type, KeyMessage(MessageType type,

View File

@ -1,4 +1,5 @@
// Aseprite UI Library // Aseprite UI Library
// Copyright (C) 2019 Igara Studio S.A.
// Copyright (C) 2001-2018 David Capello // Copyright (C) 2001-2018 David Capello
// //
// This file is released under the terms of the MIT license. // This file is released under the terms of the MIT license.
@ -13,7 +14,6 @@ namespace ui {
// Message types. // Message types.
enum MessageType { enum MessageType {
// General messages. // General messages.
kFunctionMessage, // Call a function from the UI thread.
kOpenMessage, // Windows is open. kOpenMessage, // Windows is open.
kCloseMessage, // Windows is closed. kCloseMessage, // Windows is closed.
kCloseDisplayMessage, // The user wants to close the entire application. kCloseDisplayMessage, // The user wants to close the entire application.

View File

@ -1,5 +1,5 @@
// Aseprite UI Library // Aseprite UI Library
// Copyright (C) 2018 Igara Studio S.A. // Copyright (C) 2018-2019 Igara Studio S.A.
// Copyright (C) 2001-2018 David Capello // Copyright (C) 2001-2018 David Capello
// //
// This file is released under the terms of the MIT license. // This file is released under the terms of the MIT license.
@ -14,12 +14,13 @@
#include "base/thread.h" #include "base/thread.h"
#include "gfx/point.h" #include "gfx/point.h"
#include "os/display.h" #include "os/display.h"
#include "os/event.h"
#include "os/event_queue.h"
#include "os/surface.h" #include "os/surface.h"
#include "os/system.h" #include "os/system.h"
#include "ui/clipboard_delegate.h" #include "ui/clipboard_delegate.h"
#include "ui/cursor.h" #include "ui/cursor.h"
#include "ui/intern.h" #include "ui/intern.h"
#include "ui/intern.h"
#include "ui/manager.h" #include "ui/manager.h"
#include "ui/message.h" #include "ui/message.h"
#include "ui/overlay.h" #include "ui/overlay.h"
@ -348,16 +349,13 @@ void set_mouse_position(const gfx::Point& newPos)
_internal_set_mouse_position(newPos); _internal_set_mouse_position(newPos);
} }
void execute_from_ui_thread(std::function<void()>&& f) void execute_from_ui_thread(std::function<void()>&& func)
{ {
ASSERT(Manager::getDefault()); // Queue the event
os::Event ev;
Manager* man = Manager::getDefault(); ev.setType(os::Event::Callback);
ASSERT(man); ev.setCallback(std::move(func));
os::queue_event(ev);
FunctionMessage* msg = new FunctionMessage(std::move(f));
msg->setRecipient(man);
man->enqueueMessage(msg);
} }
bool is_ui_thread() bool is_ui_thread()

View File

@ -1,4 +1,5 @@
// Aseprite UI Library // Aseprite UI Library
// Copyright (C) 2019 Igara Studio S.A.
// Copyright (C) 2001-2018 David Capello // Copyright (C) 2001-2018 David Capello
// //
// This file is released under the terms of the MIT license. // This file is released under the terms of the MIT license.
@ -70,7 +71,7 @@ namespace ui {
const gfx::Point& get_mouse_position(); const gfx::Point& get_mouse_position();
void set_mouse_position(const gfx::Point& newPos); void set_mouse_position(const gfx::Point& newPos);
void execute_from_ui_thread(std::function<void()>&& f); void execute_from_ui_thread(std::function<void()>&& func);
bool is_ui_thread(); bool is_ui_thread();
#ifdef _DEBUG #ifdef _DEBUG
void assert_ui_thread(); void assert_ui_thread();

View File

@ -1382,10 +1382,6 @@ bool Widget::onProcessMessage(Message* msg)
switch (msg->type()) { switch (msg->type()) {
case kFunctionMessage:
static_cast<FunctionMessage*>(msg)->call();
break;
case kOpenMessage: case kOpenMessage:
case kCloseMessage: case kCloseMessage:
case kWinMoveMessage: case kWinMoveMessage: