Browse Source

feat: add native emoji picker (#17359)

Shelley Vohr 6 years ago
parent
commit
12b6a0f5b2

+ 6 - 0
atom/browser/api/atom_api_app.cc

@@ -1334,6 +1334,8 @@ void App::BuildPrototype(v8::Isolate* isolate,
       .SetMethod("getLoginItemSettings", &App::GetLoginItemSettings)
       .SetMethod("setLoginItemSettings",
                  base::Bind(&Browser::SetLoginItemSettings, browser))
+      .SetMethod("isEmojiPanelSupported",
+                 base::Bind(&Browser::IsEmojiPanelSupported, browser))
 #if defined(OS_MACOSX)
       .SetMethod("hide", base::Bind(&Browser::Hide, browser))
       .SetMethod("show", base::Bind(&Browser::Show, browser))
@@ -1355,6 +1357,10 @@ void App::BuildPrototype(v8::Isolate* isolate,
       .SetMethod("showAboutPanel",
                  base::Bind(&Browser::ShowAboutPanel, browser))
 #endif
+#if defined(OS_MACOSX) || defined(OS_WIN)
+      .SetMethod("showEmojiPanel",
+                 base::Bind(&Browser::ShowEmojiPanel, browser))
+#endif
 #if defined(OS_WIN)
       .SetMethod("setUserTasks", base::Bind(&Browser::SetUserTasks, browser))
       .SetMethod("getJumpListSettings", &App::GetJumpListSettings)

+ 1 - 0
atom/browser/api/atom_api_app.h

@@ -214,6 +214,7 @@ class App : public AtomBrowserClient::Delegate,
   v8::Local<v8::Value> GetDockAPI(v8::Isolate* isolate);
   v8::Global<v8::Value> dock_;
 #endif
+
 #if defined(MAS_BUILD)
   base::Callback<void()> StartAccessingSecurityScopedResource(
       mate::Arguments* args);

+ 6 - 0
atom/browser/browser.h

@@ -187,6 +187,10 @@ class Browser : public WindowListObserver {
   void SetAboutPanelOptions(const base::DictionaryValue& options);
 #endif
 
+#if defined(OS_MACOSX) || defined(OS_WIN)
+  void ShowEmojiPanel();
+#endif
+
 #if defined(OS_WIN)
   struct UserTask {
     base::FilePath program;
@@ -230,6 +234,8 @@ class Browser : public WindowListObserver {
   // windows.
   void Activate(bool has_visible_windows);
 
+  bool IsEmojiPanelSupported();
+
   // Tell the application the loading has been done.
   void WillFinishLaunching();
   void DidFinishLaunching(const base::DictionaryValue& launch_info);

+ 4 - 0
atom/browser/browser_linux.cc

@@ -142,6 +142,10 @@ bool Browser::IsUnityRunning() {
   return unity::IsRunning();
 }
 
+bool Browser::IsEmojiPanelSupported() {
+  return false;
+}
+
 void Browser::ShowAboutPanel() {
   std::string app_name, version, copyright, icon_path, website;
 

+ 8 - 0
atom/browser/browser_mac.mm

@@ -411,4 +411,12 @@ void Browser::SetAboutPanelOptions(const base::DictionaryValue& options) {
   }
 }
 
+void Browser::ShowEmojiPanel() {
+  [[AtomApplication sharedApplication] orderFrontCharacterPalette:nil];
+}
+
+bool Browser::IsEmojiPanelSupported() {
+  return true;
+}
+
 }  // namespace atom

+ 25 - 0
atom/browser/browser_win.cc

@@ -25,6 +25,7 @@
 #include "base/win/registry.h"
 #include "base/win/win_util.h"
 #include "base/win/windows_version.h"
+#include "ui/events/keycodes/keyboard_code_conversion_win.h"
 
 namespace atom {
 
@@ -343,4 +344,28 @@ std::string Browser::GetExecutableFileProductName() const {
   return GetApplicationName();
 }
 
+bool Browser::IsEmojiPanelSupported() {
+  // emoji picker is supported on Windows 10's Spring 2018 update & above.
+  return base::win::GetVersion() >= base::win::Version::VERSION_WIN10_RS4;
+}
+
+void Browser::ShowEmojiPanel() {
+  // This sends Windows Key + '.' (both keydown and keyup events).
+  // "SendInput" is used because Windows needs to receive these events and
+  // open the Emoji picker.
+  INPUT input[4] = {};
+  input[0].type = INPUT_KEYBOARD;
+  input[0].ki.wVk = ui::WindowsKeyCodeForKeyboardCode(ui::VKEY_COMMAND);
+  input[1].type = INPUT_KEYBOARD;
+  input[1].ki.wVk = ui::WindowsKeyCodeForKeyboardCode(ui::VKEY_OEM_PERIOD);
+
+  input[2].type = INPUT_KEYBOARD;
+  input[2].ki.wVk = ui::WindowsKeyCodeForKeyboardCode(ui::VKEY_COMMAND);
+  input[2].ki.dwFlags |= KEYEVENTF_KEYUP;
+  input[3].type = INPUT_KEYBOARD;
+  input[3].ki.wVk = ui::WindowsKeyCodeForKeyboardCode(ui::VKEY_OEM_PERIOD);
+  input[3].ki.dwFlags |= KEYEVENTF_KEYUP;
+  ::SendInput(4, input, sizeof(INPUT));
+}
+
 }  // namespace atom

+ 8 - 0
docs/api/app.md

@@ -1179,6 +1179,14 @@ Show the app's about panel options. These options can be overridden with `app.se
 Set the about panel options. This will override the values defined in the app's
 `.plist` file on MacOS. See the [Apple docs][about-panel-options] for more details. On Linux, values must be set in order to be shown; there are no defaults.
 
+### `app.isEmojiPanelSupported`
+
+Returns `Boolean` - whether or not the current OS version allows for native emoji pickers.
+
+### `app.showEmojiPanel` _macOS_ _Windows_
+
+Show the platform's native emoji picker.
+
 ### `app.startAccessingSecurityScopedResource(bookmarkData)` _macOS (mas)_
 
 * `bookmarkData` String - The base64 encoded security scoped bookmark data returned by the `dialog.showOpenDialog` or `dialog.showSaveDialog` methods.