Fix macOS bug executing commands from other native menu instead of the open aseprite menubox when we use mnemonics

This commit is contained in:
David Capello 2018-06-29 12:14:54 -03:00
parent 4d885b5b8a
commit 3e0ebd34c9
3 changed files with 43 additions and 29 deletions

View File

@ -103,6 +103,14 @@ bool can_call_global_shortcut(const AppMenuItem::Native* native)
// The foreground window must be the main window to avoid calling
// a global command inside a modal dialog.
(manager->getForegroundWindow() == App::instance()->mainWindow()) &&
// If we are in a menubox window (e.g. we've pressed
// Alt+mnemonic), we should disable the native shortcuts
// temporarily so we can use mnemonics without modifiers
// (e.g. Alt+S opens the Sprite menu, then 'S' key should execute
// "Sprite Size" command in that menu, instead of Stroke command
// which is in 'Edit > Stroke'). This is necessary in macOS, when
// the native menu + Aseprite pixel-art menus are enabled.
(dynamic_cast<MenuBoxWindow*>(manager->getTopWindow()) == nullptr) &&
// The focused widget cannot be an entry, because entry fields
// prefer text input, so we cannot call shortcuts without
// modifiers (e.g. F or T keystrokes) to trigger a global command

View File

@ -87,32 +87,6 @@ struct MenuBaseData {
};
class CustomizedWindowForMenuBox : public Window
{
public:
CustomizedWindowForMenuBox(MenuBox* menubox)
: Window(WithoutTitleBar, "")
{
setMoveable(false); // Can't move the window
addChild(menubox);
remapWindow();
}
protected:
bool onProcessMessage(Message* msg) override
{
switch (msg->type()) {
case kCloseMessage:
// Delete this window automatically
deferDelete();
break;
}
return Window::onProcessMessage(msg);
}
};
static MenuBox* get_base_menubox(Widget* widget);
static MenuBaseData* get_base(Widget* widget);
@ -747,7 +721,7 @@ bool MenuItem::onProcessMessage(Message* msg)
menubox->setMenu(m_submenu);
// New window and new menu-box
Window* window = new CustomizedWindowForMenuBox(menubox);
Window* window = new MenuBoxWindow(menubox);
// Menubox position
Rect pos = window->bounds();
@ -847,7 +821,7 @@ bool MenuItem::onProcessMessage(Message* msg)
manager()->setFocus(this->parent()->parent());
// Do not call "delete window" here, because it
// (CustomizedWindowForMenuBox) will be deferDelete()d on
// (MenuBoxWindow) will be deferDelete() on
// kCloseMessage.
if (last_of_close_chain) {
@ -1306,4 +1280,28 @@ static MenuItem* find_previtem(Menu* menu, MenuItem* menuitem)
return NULL;
}
//////////////////////////////////////////////////////////////////////
// MenuBoxWindow
MenuBoxWindow::MenuBoxWindow(MenuBox* menubox)
: Window(WithoutTitleBar, "")
{
setMoveable(false); // Can't move the window
addChild(menubox);
remapWindow();
}
bool MenuBoxWindow::onProcessMessage(Message* msg)
{
switch (msg->type()) {
case kCloseMessage:
// Delete this window automatically
deferDelete();
break;
}
return Window::onProcessMessage(msg);
}
} // namespace ui

View File

@ -1,5 +1,5 @@
// Aseprite UI Library
// Copyright (C) 2001-2017 David Capello
// Copyright (C) 2001-2018 David Capello
//
// This file is released under the terms of the MIT license.
// Read LICENSE.txt for more information.
@ -13,6 +13,7 @@
#include "ui/register_message.h"
#include "ui/separator.h"
#include "ui/widget.h"
#include "ui/window.h"
namespace ui {
@ -160,6 +161,13 @@ namespace ui {
}
};
class MenuBoxWindow : public Window {
public:
MenuBoxWindow(MenuBox* menubox);
protected:
bool onProcessMessage(Message* msg) override;
};
extern RegisterMessage kOpenMenuItemMessage;
extern RegisterMessage kCloseMenuItemMessage;
extern RegisterMessage kClosePopupMessage;