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

View File

@ -1,5 +1,5 @@
// Aseprite UI Library
// Copyright (C) 2018 Igara Studio S.A.
// Copyright (C) 2018-2019 Igara Studio S.A.
// Copyright (C) 2001-2018 David Capello
//
// This file is released under the terms of the MIT license.
@ -18,8 +18,6 @@
#include "ui/mouse_buttons.h"
#include "ui/pointer_type.h"
#include <functional>
namespace ui {
class Timer;
@ -79,16 +77,6 @@ namespace ui {
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 {
public:
KeyMessage(MessageType type,

View File

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

View File

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

View File

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

View File

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