feat: implement 'app-command' events for browser history navigation keys on Linux (#15441)

* Added mouse forward/back button support on Linux

* Added browser history navigation action bindings for Windows, Mac, and Linux keyboard

* Removed new `history-action` event and modified `app-command` to execute on such events

* Removed attempt at macOS support and added constants

* Clarified app-command documentation

* Reverted 'app-command' description change

* Format code
This commit is contained in:
Saswat Bhattacharya 2018-12-05 09:35:59 -08:00 committed by Shelley Vohr
parent 3f15f51615
commit d243a45173
11 changed files with 64 additions and 12 deletions

View file

@ -267,7 +267,7 @@ void TopLevelWindow::OnWindowAlwaysOnTopChanged() {
Emit("always-on-top-changed", IsAlwaysOnTop()); Emit("always-on-top-changed", IsAlwaysOnTop());
} }
void TopLevelWindow::OnExecuteWindowsCommand(const std::string& command_name) { void TopLevelWindow::OnExecuteAppCommand(const std::string& command_name) {
Emit("app-command", command_name); Emit("app-command", command_name);
} }

View file

@ -78,7 +78,7 @@ class TopLevelWindow : public mate::TrackableObject<TopLevelWindow>,
void OnWindowEnterHtmlFullScreen() override; void OnWindowEnterHtmlFullScreen() override;
void OnWindowLeaveHtmlFullScreen() override; void OnWindowLeaveHtmlFullScreen() override;
void OnWindowAlwaysOnTopChanged() override; void OnWindowAlwaysOnTopChanged() override;
void OnExecuteWindowsCommand(const std::string& command_name) override; void OnExecuteAppCommand(const std::string& command_name) override;
void OnTouchBarItemResult(const std::string& item_id, void OnTouchBarItemResult(const std::string& item_id,
const base::DictionaryValue& details) override; const base::DictionaryValue& details) override;
void OnNewWindowForTab() override; void OnNewWindowForTab() override;

View file

@ -540,10 +540,9 @@ void NativeWindow::NotifyWindowAlwaysOnTopChanged() {
observer.OnWindowAlwaysOnTopChanged(); observer.OnWindowAlwaysOnTopChanged();
} }
void NativeWindow::NotifyWindowExecuteWindowsCommand( void NativeWindow::NotifyWindowExecuteAppCommand(const std::string& command) {
const std::string& command) {
for (NativeWindowObserver& observer : observers_) for (NativeWindowObserver& observer : observers_)
observer.OnExecuteWindowsCommand(command); observer.OnExecuteAppCommand(command);
} }
void NativeWindow::NotifyTouchBarItemInteraction( void NativeWindow::NotifyTouchBarItemInteraction(

View file

@ -257,7 +257,7 @@ class NativeWindow : public base::SupportsUserData,
void NotifyWindowEnterHtmlFullScreen(); void NotifyWindowEnterHtmlFullScreen();
void NotifyWindowLeaveHtmlFullScreen(); void NotifyWindowLeaveHtmlFullScreen();
void NotifyWindowAlwaysOnTopChanged(); void NotifyWindowAlwaysOnTopChanged();
void NotifyWindowExecuteWindowsCommand(const std::string& command); void NotifyWindowExecuteAppCommand(const std::string& command);
void NotifyTouchBarItemInteraction(const std::string& item_id, void NotifyTouchBarItemInteraction(const std::string& item_id,
const base::DictionaryValue& details); const base::DictionaryValue& details);
void NotifyNewWindowForTab(); void NotifyNewWindowForTab();

View file

@ -95,7 +95,8 @@ class NativeWindowObserver : public base::CheckedObserver {
#endif #endif
// Called on Windows when App Commands arrive (WM_APPCOMMAND) // Called on Windows when App Commands arrive (WM_APPCOMMAND)
virtual void OnExecuteWindowsCommand(const std::string& command_name) {} // Some commands are implemented on on other platforms as well
virtual void OnExecuteAppCommand(const std::string& command_name) {}
}; };
} // namespace atom } // namespace atom

View file

@ -22,6 +22,7 @@
#include "atom/browser/web_contents_preferences.h" #include "atom/browser/web_contents_preferences.h"
#include "atom/browser/web_view_manager.h" #include "atom/browser/web_view_manager.h"
#include "atom/browser/window_list.h" #include "atom/browser/window_list.h"
#include "atom/common/atom_constants.h"
#include "atom/common/draggable_region.h" #include "atom/common/draggable_region.h"
#include "atom/common/native_mate_converters/image_converter.h" #include "atom/common/native_mate_converters/image_converter.h"
#include "atom/common/options_switches.h" #include "atom/common/options_switches.h"
@ -287,6 +288,13 @@ NativeWindowViews::NativeWindowViews(const mate::Dictionary& options,
last_window_state_ = ui::SHOW_STATE_NORMAL; last_window_state_ = ui::SHOW_STATE_NORMAL;
last_normal_bounds_ = GetBounds(); last_normal_bounds_ = GetBounds();
#endif #endif
#if defined(OS_LINUX)
// Listen to move events.
aura::Window* window = GetNativeWindow();
if (window)
window->AddPreTargetHandler(this);
#endif
} }
NativeWindowViews::~NativeWindowViews() { NativeWindowViews::~NativeWindowViews() {
@ -296,6 +304,12 @@ NativeWindowViews::~NativeWindowViews() {
// Disable mouse forwarding to relinquish resources, should any be held. // Disable mouse forwarding to relinquish resources, should any be held.
SetForwardMouseMessages(false); SetForwardMouseMessages(false);
#endif #endif
#if defined(OS_LINUX)
aura::Window* window = GetNativeWindow();
if (window)
window->RemovePreTargetHandler(this);
#endif
} }
void NativeWindowViews::SetContentView(views::View* view) { void NativeWindowViews::SetContentView(views::View* view) {
@ -1274,11 +1288,30 @@ void NativeWindowViews::OnWidgetMove() {
void NativeWindowViews::HandleKeyboardEvent( void NativeWindowViews::HandleKeyboardEvent(
content::WebContents*, content::WebContents*,
const content::NativeWebKeyboardEvent& event) { const content::NativeWebKeyboardEvent& event) {
#if defined(OS_LINUX)
if (event.windows_key_code == ui::VKEY_BROWSER_BACK)
NotifyWindowExecuteAppCommand(kBrowserBackward);
else if (event.windows_key_code == ui::VKEY_BROWSER_FORWARD)
NotifyWindowExecuteAppCommand(kBrowserForward);
#endif
keyboard_event_handler_->HandleKeyboardEvent(event, keyboard_event_handler_->HandleKeyboardEvent(event,
root_view_->GetFocusManager()); root_view_->GetFocusManager());
root_view_->HandleKeyEvent(event); root_view_->HandleKeyEvent(event);
} }
#if defined(OS_LINUX)
void NativeWindowViews::OnMouseEvent(ui::MouseEvent* event) {
if (event->type() != ui::ET_MOUSE_PRESSED)
return;
if (event->changed_button_flags() == ui::EF_BACK_MOUSE_BUTTON)
NotifyWindowExecuteAppCommand(kBrowserBackward);
else if (event->changed_button_flags() == ui::EF_FORWARD_MOUSE_BUTTON)
NotifyWindowExecuteAppCommand(kBrowserForward);
}
#endif
ui::WindowShowState NativeWindowViews::GetRestoredState() { ui::WindowShowState NativeWindowViews::GetRestoredState() {
if (IsMaximized()) if (IsMaximized())
return ui::SHOW_STATE_MAXIMIZED; return ui::SHOW_STATE_MAXIMIZED;

View file

@ -40,7 +40,8 @@ class NativeWindowViews : public NativeWindow,
#if defined(OS_WIN) #if defined(OS_WIN)
public MessageHandlerDelegate, public MessageHandlerDelegate,
#endif #endif
public views::WidgetObserver { public views::WidgetObserver,
public ui::EventHandler {
public: public:
NativeWindowViews(const mate::Dictionary& options, NativeWindow* parent); NativeWindowViews(const mate::Dictionary& options, NativeWindow* parent);
~NativeWindowViews() override; ~NativeWindowViews() override;
@ -204,6 +205,11 @@ class NativeWindowViews : public NativeWindow,
content::WebContents*, content::WebContents*,
const content::NativeWebKeyboardEvent& event) override; const content::NativeWebKeyboardEvent& event) override;
#if defined(OS_LINUX)
// ui::EventHandler:
void OnMouseEvent(ui::MouseEvent* event) override;
#endif
// Returns the restore state for the window. // Returns the restore state for the window.
ui::WindowShowState GetRestoredState(); ui::WindowShowState GetRestoredState();

View file

@ -4,6 +4,7 @@
#include "atom/browser/browser.h" #include "atom/browser/browser.h"
#include "atom/browser/native_window_views.h" #include "atom/browser/native_window_views.h"
#include "atom/common/atom_constants.h"
#include "content/public/browser/browser_accessibility_state.h" #include "content/public/browser/browser_accessibility_state.h"
#include "ui/base/win/accessibility_misc_utils.h" #include "ui/base/win/accessibility_misc_utils.h"
@ -18,9 +19,9 @@ namespace {
const char* AppCommandToString(int command_id) { const char* AppCommandToString(int command_id) {
switch (command_id) { switch (command_id) {
case APPCOMMAND_BROWSER_BACKWARD: case APPCOMMAND_BROWSER_BACKWARD:
return "browser-backward"; return kBrowserBackward;
case APPCOMMAND_BROWSER_FORWARD: case APPCOMMAND_BROWSER_FORWARD:
return "browser-forward"; return kBrowserForward;
case APPCOMMAND_BROWSER_REFRESH: case APPCOMMAND_BROWSER_REFRESH:
return "browser-refresh"; return "browser-refresh";
case APPCOMMAND_BROWSER_STOP: case APPCOMMAND_BROWSER_STOP:
@ -141,7 +142,7 @@ HHOOK NativeWindowViews::mouse_hook_ = NULL;
bool NativeWindowViews::ExecuteWindowsCommand(int command_id) { bool NativeWindowViews::ExecuteWindowsCommand(int command_id) {
std::string command = AppCommandToString(command_id); std::string command = AppCommandToString(command_id);
NotifyWindowExecuteWindowsCommand(command); NotifyWindowExecuteAppCommand(command);
return false; return false;
} }

View file

@ -6,6 +6,9 @@
namespace atom { namespace atom {
const char kBrowserForward[] = "browser-forward";
const char kBrowserBackward[] = "browser-backward";
const char kCORSHeader[] = "Access-Control-Allow-Origin: *"; const char kCORSHeader[] = "Access-Control-Allow-Origin: *";
const char kSHA1Certificate[] = "SHA-1 Certificate"; const char kSHA1Certificate[] = "SHA-1 Certificate";

View file

@ -9,6 +9,10 @@
namespace atom { namespace atom {
// The app-command in NativeWindow.
extern const char kBrowserForward[];
extern const char kBrowserBackward[];
// Header to ignore CORS. // Header to ignore CORS.
extern const char kCORSHeader[]; extern const char kCORSHeader[];

View file

@ -554,7 +554,7 @@ Returns:
Emitted when the window is set or unset to show always on top of other windows. Emitted when the window is set or unset to show always on top of other windows.
#### Event: 'app-command' _Windows_ #### Event: 'app-command' _Windows_ _Linux_
Returns: Returns:
@ -580,6 +580,11 @@ win.on('app-command', (e, cmd) => {
}) })
``` ```
The following app commands are explictly supported on Linux:
* `browser-backward`
* `browser-forward`
#### Event: 'scroll-touch-begin' _macOS_ #### Event: 'scroll-touch-begin' _macOS_
Emitted when scroll wheel event phase has begun. Emitted when scroll wheel event phase has begun.