Skip to content
This repository has been archived by the owner on Sep 2, 2021. It is now read-only.

Implement modality of a JS dialog in app shell by using a new api. #268

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions appshell/appshell_extensions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -626,6 +626,22 @@ class ProcessMessageDelegate : public ClientHandler::ProcessMessageDelegate {
responseArgs->SetString(2, parentId);
responseArgs->SetInt(3, index);
}
} else if (message_name == "SetModal") {
// Parameters:
// 0: int32 - callback id
// 1: bool - on or off
if (argList->GetSize() != 2 ||
argList->GetType(1) != VTYPE_BOOL) {
error = ERR_INVALID_PARAMS;
}

if (error == NO_ERROR) {
bool hasModalDialog = argList->GetBool(1);
handler->SetModal(browser, hasModalDialog);
}

// No additional response args for this function

} else if (message_name == "DragWindow") {
// Parameters: none
DragWindow(browser);
Expand Down
8 changes: 8 additions & 0 deletions appshell/appshell_extensions.js
Original file line number Diff line number Diff line change
Expand Up @@ -689,6 +689,14 @@ if (!appshell.app) {
GetMenuPosition(callback, commandId);
};

/**
* Set the global variable that represents the display of a modal dialog.
*/
native function SetModal();
appshell.app.setModal = function (hasModalDialog, callback) {
SetModal(callback || _dummyCallback, hasModalDialog);
};

/**
* Return the user's language per operating system preferences.
*/
Expand Down
9 changes: 6 additions & 3 deletions appshell/appshell_extensions_mac.mm
Original file line number Diff line number Diff line change
Expand Up @@ -629,11 +629,14 @@ void OnBeforeShutdown()
void CloseWindow(CefRefPtr<CefBrowser> browser)
{
NSWindow* window = [browser->GetHost()->GetWindowHandle() window];
bool hasModalDialog = [[window delegate] performSelector:@selector(isShowingModalDialog)];

// Tell the window delegate it's really time to close
[[window delegate] performSelector:@selector(setIsReallyClosing)];
browser->GetHost()->CloseBrowser(true);
[window close];
if (!hasModalDialog) {
[[window delegate] performSelector:@selector(setIsReallyClosing)];
browser->GetHost()->CloseBrowser(true);
[window close];
}
}

void BringBrowserWindowToFront(CefRefPtr<CefBrowser> browser)
Expand Down
2 changes: 0 additions & 2 deletions appshell/appshell_extensions_win.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1684,6 +1684,4 @@ void DragWindow(CefRefPtr<CefBrowser> browser) {
HWND browserHwnd = (HWND)getMenuParent(browser);
SendMessage(browserHwnd, WM_NCLBUTTONDOWN, HTCAPTION, 0);
}



12 changes: 12 additions & 0 deletions appshell/cefclient_mac.mm
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,14 @@ - (id) init {
return self;
}

- (bool)isShowingModalDialog {
bool hasModalDialog = false;
if (g_handler.get() && g_handler->GetBrowserId()) {
hasModalDialog = g_handler->HasModalDialog(g_handler->GetBrowser());
}
return hasModalDialog;
}

- (void)setIsReallyClosing {
isReallyClosing = true;
}
Expand All @@ -175,10 +183,14 @@ - (BOOL)validateMenuItem:(NSMenuItem *)menuItem {
NSInteger menuState = NSOffState;
NSUInteger tag = [menuItem tag];
NativeMenuModel menus = NativeMenuModel::getInstance(getMenuParent(g_handler->GetBrowser()));
ExtensionString commandId = menus.getCommandId(tag);
if (menus.isMenuItemChecked(tag)) {
menuState = NSOnState;
}
[menuItem setState:menuState];
if (g_handler->HasModalDialog(g_handler->GetBrowser()) && !IsEditCommandId(commandId)) {
return false;
}
return menus.isMenuItemEnabled(tag);
}

Expand Down
12 changes: 8 additions & 4 deletions appshell/cefclient_win.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -857,7 +857,7 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam,

case WM_CLOSE:
if (g_handler.get()) {

bool hasModalDialog = g_handler->HasModalDialog(g_handler->GetBrowser());
HWND hWnd = GetActiveWindow();
SaveWindowRect(hWnd);

Expand All @@ -869,8 +869,10 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam,
break;
}

g_handler->QuittingApp(true);
g_handler->DispatchCloseToNextBrowser();
if (!hasModalDialog) {
g_handler->QuittingApp(true);
g_handler->DispatchCloseToNextBrowser();
}
return 0;
}
break;
Expand All @@ -893,11 +895,13 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam,
HMENU menu = (HMENU)wParam;
int count = GetMenuItemCount(menu);
void* menuParent = getMenuParent(g_handler->GetBrowser());
bool hasModalDialog = g_handler->HasModalDialog(g_handler->GetBrowser());

for (int i = 0; i < count; i++) {
UINT id = GetMenuItemID(menu, i);

bool enabled = NativeMenuModel::getInstance(menuParent).isMenuItemEnabled(id);
UINT flagEnabled = enabled ? MF_ENABLED | MF_BYCOMMAND : MF_DISABLED | MF_BYCOMMAND;
UINT flagEnabled = (enabled && !hasModalDialog) ? MF_ENABLED | MF_BYCOMMAND : MF_DISABLED | MF_BYCOMMAND;
EnableMenuItem(menu, id, flagEnabled);

bool checked = NativeMenuModel::getInstance(menuParent).isMenuItemChecked(id);
Expand Down
19 changes: 19 additions & 0 deletions appshell/client_handler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ enum client_menu_ids {
};

ClientHandler::BrowserWindowMap ClientHandler::browser_window_map_;
ClientHandler::BrowserWindowMap ClientHandler::modal_browser_window_map_;

ClientHandler::ClientHandler()
: m_MainHwnd(NULL),
Expand Down Expand Up @@ -334,6 +335,24 @@ bool ClientHandler::SendJSCommand(CefRefPtr<CefBrowser> browser, const CefString
return browser->SendProcessMessage(PID_RENDERER, message);
}

bool ClientHandler::HasModalDialog(CefRefPtr<CefBrowser> browser) {
if (browser.get() && modal_browser_window_map_.size() > 0) {
BrowserWindowMap::const_iterator it = modal_browser_window_map_.find(browser->GetHost()->GetWindowHandle());
return it != modal_browser_window_map_.end();
}
return false;
}

void ClientHandler::SetModal(CefRefPtr<CefBrowser> browser, bool hasModalDialog) {
if (browser.get()) {
if (hasModalDialog) {
modal_browser_window_map_[browser->GetHost()->GetWindowHandle()] = browser;
} else {
modal_browser_window_map_.erase(browser->GetHost()->GetWindowHandle());
}
}
}

void ClientHandler::SendOpenFileCommand(CefRefPtr<CefBrowser> browser, const CefString &filename) {
std::string filenameStr(filename);
// FIXME: Use SendJSCommand once it supports parameters
Expand Down
4 changes: 4 additions & 0 deletions appshell/client_handler.h
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,9 @@ class ClientHandler : public CefClient,
bool AppIsQuitting() { return m_quitting; }
bool HasWindows() const { return !browser_window_map_.empty(); }

void SetModal(CefRefPtr<CefBrowser> browser, bool hasModalDialog);
bool HasModalDialog(CefRefPtr<CefBrowser> browser);

protected:
void SetLoading(bool isLoading);
void SetNavState(bool canGoBack, bool canGoForward);
Expand Down Expand Up @@ -259,6 +262,7 @@ class ClientHandler : public CefClient,

typedef std::map< CefWindowHandle, CefRefPtr<CefBrowser> > BrowserWindowMap;
static BrowserWindowMap browser_window_map_;
static BrowserWindowMap modal_browser_window_map_;

typedef std::map<int32, CefRefPtr<CommandCallback> > CommandCallbackMap;
int32 callbackId;
Expand Down
13 changes: 13 additions & 0 deletions appshell/client_handler_mac.mm
Original file line number Diff line number Diff line change
Expand Up @@ -136,10 +136,14 @@ - (BOOL)validateMenuItem:(NSMenuItem *)menuItem {
NSInteger menuState = NSOffState;
NSUInteger tag = [menuItem tag];
NativeMenuModel menus = NativeMenuModel::getInstance(getMenuParent(browser));
ExtensionString commandId = menus.getCommandId(tag);
if (menus.isMenuItemChecked(tag)) {
menuState = NSOnState;
}
[menuItem setState:menuState];
if (clientHandler->HasModalDialog(browser) && !IsEditCommandId(commandId)) {
return false;
}
return menus.isMenuItemEnabled(tag);
}

Expand All @@ -151,6 +155,15 @@ - (void)setWindow:(NSWindow*)win {
window = win;
}

- (bool)isShowingModalDialog {
bool hasModalDialog = false;
if (clientHandler.get() && clientHandler->GetBrowserId()) {
CefRefPtr<CefBrowser> browser = ClientHandler::GetBrowserForNativeWindow(window);
hasModalDialog = clientHandler->HasModalDialog(browser);
}
return hasModalDialog;
}

- (void)setIsReallyClosing {
isReallyClosing = true;
}
Expand Down
18 changes: 13 additions & 5 deletions appshell/client_handler_win.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -134,15 +134,18 @@ LRESULT CALLBACK PopupWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lPa

case WM_CLOSE:
if (g_handler.get() && browser.get()) {
bool hasModalDialog = g_handler->HasModalDialog(browser);
HWND browserHwnd = browser->GetHost()->GetWindowHandle();
HANDLE closing = GetProp(browserHwnd, CLOSING_PROP);
if (closing) {
RemoveProp(browserHwnd, CLOSING_PROP);
break;
}

CefRefPtr<CommandCallback> callback = new CloseWindowCommandCallback(browser);
g_handler->SendJSCommand(browser, FILE_CLOSE_WINDOW, callback);
if (!hasModalDialog) {
CefRefPtr<CommandCallback> callback = new CloseWindowCommandCallback(browser);
g_handler->SendJSCommand(browser, FILE_CLOSE_WINDOW, callback);
}
return 0;
}
break;
Expand All @@ -157,11 +160,13 @@ LRESULT CALLBACK PopupWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lPa
HMENU menu = (HMENU)wParam;
int count = GetMenuItemCount(menu);
void* menuParent = getMenuParent(browser);
bool hasModalDialog = g_handler->HasModalDialog(browser);

for (int i = 0; i < count; i++) {
UINT id = GetMenuItemID(menu, i);

bool enabled = NativeMenuModel::getInstance(menuParent).isMenuItemEnabled(id);
UINT flagEnabled = enabled ? MF_ENABLED | MF_BYCOMMAND : MF_DISABLED | MF_BYCOMMAND;
UINT flagEnabled = (enabled && !hasModalDialog) ? MF_ENABLED | MF_BYCOMMAND : MF_DISABLED | MF_BYCOMMAND;
EnableMenuItem(menu, id, flagEnabled);

bool checked = NativeMenuModel::getInstance(menuParent).isMenuItemChecked(id);
Expand Down Expand Up @@ -249,8 +254,11 @@ bool ClientHandler::OnPreKeyEvent(CefRefPtr<CefBrowser> browser,
bool* is_keyboard_shortcut) {
HWND frameHwnd = (HWND)getMenuParent(browser);

// Don't call ::TranslateAccelerator if we don't have a menu for the current window.
if (!GetMenu(frameHwnd)) {
// Don't call ::TranslateAccelerator if we don't have a menu for the current window or
// if we have a modal dialog showing for the current window.
if (!GetMenu(frameHwnd) ||
(modal_browser_window_map_.size() > 0 && browser.get() &&
modal_browser_window_map_.find(browser->GetHost()->GetWindowHandle()) != modal_browser_window_map_.end())) {
return false;
}

Expand Down
9 changes: 9 additions & 0 deletions appshell/command_callbacks.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,15 @@ const ExtensionString EDIT_PASTE = "edit.paste";
const ExtensionString EDIT_SELECT_ALL = "edit.selectAll";
#endif

inline bool IsEditCommandId(ExtensionString commandId) {
return (commandId == EDIT_UNDO) ||
(commandId == EDIT_REDO) ||
(commandId == EDIT_CUT) ||
(commandId == EDIT_COPY) ||
(commandId == EDIT_PASTE) ||
(commandId == EDIT_SELECT_ALL);
}

// Base CommandCallback class
class CommandCallback : public CefBase {

Expand Down