15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "win8/metro_driver/stdafx.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "win8/metro_driver/chrome_app_view_ash.h"
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include <corewindow.h>
9868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include <shellapi.h>
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <windows.foundation.h>
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h"
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/command_line.h"
1458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "base/files/file_path.h"
159ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/message_loop/message_loop.h"
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/path_service.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/win/metro.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/win/win_util.h"
19effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "base/win/windows_version.h"
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/common/chrome_switches.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ipc/ipc_channel.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ipc/ipc_channel_proxy.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ipc/ipc_sender.h"
241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "ui/events/gesture_detection/motion_event.h"
25cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "ui/gfx/geometry/point_conversions.h"
26cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "ui/gfx/win/dpi.h"
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/metro_viewer/metro_viewer_messages.h"
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "win8/metro_driver/file_picker_ash.h"
295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "win8/metro_driver/ime/ime_popup_monitor.h"
30a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "win8/metro_driver/ime/input_source.h"
31a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "win8/metro_driver/ime/text_service.h"
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "win8/metro_driver/metro_driver.h"
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "win8/metro_driver/winrt_utils.h"
34eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "win8/viewer/metro_viewer_constants.h"
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef winfoundtn::ITypedEventHandler<
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    winapp::Core::CoreApplicationView*,
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    winapp::Activation::IActivatedEventArgs*> ActivatedHandler;
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef winfoundtn::ITypedEventHandler<
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    winui::Core::CoreWindow*,
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    winui::Core::PointerEventArgs*> PointerEventHandler;
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef winfoundtn::ITypedEventHandler<
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    winui::Core::CoreWindow*,
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    winui::Core::KeyEventArgs*> KeyEventHandler;
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef winfoundtn::ITypedEventHandler<
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    winui::Core::CoreDispatcher*,
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    winui::Core::AcceleratorKeyEventArgs*> AcceleratorKeyEventHandler;
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)typedef winfoundtn::ITypedEventHandler<
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    winui::Core::CoreWindow*,
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    winui::Core::CharacterReceivedEventArgs*> CharEventHandler;
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)typedef winfoundtn::ITypedEventHandler<
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    winui::Core::CoreWindow*,
58c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    winui::Core::WindowActivatedEventArgs*> WindowActivatedHandler;
59c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)typedef winfoundtn::ITypedEventHandler<
617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    winui::Core::CoreWindow*,
627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    winui::Core::WindowSizeChangedEventArgs*> SizeChangedHandler;
637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
64f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)typedef winfoundtn::ITypedEventHandler<
65f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    winui::Input::EdgeGesture*,
66f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    winui::Input::EdgeGestureEventArgs*> EdgeEventHandler;
67f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This function is exported by chrome.exe.
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef int (__cdecl *BreakpadExceptionHandler)(EXCEPTION_POINTERS* info);
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Global information used across the metro driver.
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct Globals {
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  winapp::Activation::ApplicationExecutionState previous_state;
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  winapp::Core::ICoreApplicationExit* app_exit;
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BreakpadExceptionHandler breakpad_exception_handler;
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} globals;
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
78cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)extern float GetModernUIScale();
79cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
82f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)enum KeyModifier {
83f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  NONE,
84f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  SHIFT = 1,
85f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  CONTROL = 2,
86f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ALT = 4
87f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)};
88f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciconst int kChromeChannelPollTimerMs = 100;
901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
91f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Helper function to send keystrokes via the SendInput function.
92f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// mnemonic_char: The keystroke to be sent.
93f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// modifiers: Combination with Alt, Ctrl, Shift, etc.
94a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void SendKeySequence(
95f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    WORD mnemonic_char, KeyModifier modifiers) {
96f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  INPUT keys[4] = {0};  // Keyboard events
97f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  int key_count = 0;  // Number of generated events
98f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
99f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (modifiers & SHIFT) {
100f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    keys[key_count].type = INPUT_KEYBOARD;
101f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    keys[key_count].ki.wVk = VK_SHIFT;
102f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    keys[key_count].ki.wScan = MapVirtualKey(VK_SHIFT, 0);
103f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    key_count++;
104f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
105f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
106f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (modifiers & CONTROL) {
107f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    keys[key_count].type = INPUT_KEYBOARD;
108f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    keys[key_count].ki.wVk = VK_CONTROL;
109f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    keys[key_count].ki.wScan = MapVirtualKey(VK_CONTROL, 0);
110f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    key_count++;
111f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
112f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
113f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (modifiers & ALT) {
114f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    keys[key_count].type = INPUT_KEYBOARD;
115f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    keys[key_count].ki.wVk = VK_MENU;
116f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    keys[key_count].ki.wScan = MapVirtualKey(VK_MENU, 0);
117f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    key_count++;
118f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
119f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
120f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  keys[key_count].type = INPUT_KEYBOARD;
121f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  keys[key_count].ki.wVk = mnemonic_char;
122f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  keys[key_count].ki.wScan = MapVirtualKey(mnemonic_char, 0);
123f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  key_count++;
124f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
125f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  bool should_sleep = key_count > 1;
126f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
127f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Send key downs.
128f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  for (int i = 0; i < key_count; i++) {
129f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    SendInput(1, &keys[ i ], sizeof(keys[0]));
130f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    keys[i].ki.dwFlags |= KEYEVENTF_KEYUP;
131f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (should_sleep)
132f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      Sleep(10);
133f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
134f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
135f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Now send key ups in reverse order.
136f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  for (int i = key_count; i; i--) {
137f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    SendInput(1, &keys[ i - 1 ], sizeof(keys[0]));
138f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (should_sleep)
139f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      Sleep(10);
140f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
141f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
142f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ChromeChannelListener : public IPC::Listener {
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
145c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ChromeChannelListener(base::MessageLoop* ui_loop, ChromeAppViewAsh* app_view)
1468bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      : ui_proxy_(ui_loop->message_loop_proxy()),
1478bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)        app_view_(app_view) {}
1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE {
1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    IPC_BEGIN_MESSAGE_MAP(ChromeChannelListener, message)
1510f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      IPC_MESSAGE_HANDLER(MetroViewerHostMsg_ActivateDesktop,
1520f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                          OnActivateDesktop)
1535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      IPC_MESSAGE_HANDLER(MetroViewerHostMsg_MetroExit, OnMetroExit)
15458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      IPC_MESSAGE_HANDLER(MetroViewerHostMsg_OpenURLOnDesktop,
15558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                          OnOpenURLOnDesktop)
1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      IPC_MESSAGE_HANDLER(MetroViewerHostMsg_SetCursor, OnSetCursor)
1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      IPC_MESSAGE_HANDLER(MetroViewerHostMsg_DisplayFileOpen,
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          OnDisplayFileOpenDialog)
1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      IPC_MESSAGE_HANDLER(MetroViewerHostMsg_DisplayFileSaveAs,
1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          OnDisplayFileSaveAsDialog)
161c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      IPC_MESSAGE_HANDLER(MetroViewerHostMsg_DisplaySelectFolder,
162c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                          OnDisplayFolderPicker)
163b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      IPC_MESSAGE_HANDLER(MetroViewerHostMsg_SetCursorPos, OnSetCursorPos)
164a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      IPC_MESSAGE_HANDLER(MetroViewerHostMsg_ImeCancelComposition,
165a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                          OnImeCancelComposition)
166a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      IPC_MESSAGE_HANDLER(MetroViewerHostMsg_ImeTextInputClientUpdated,
167a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                          OnImeTextInputClientChanged)
1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      IPC_MESSAGE_UNHANDLED(__debugbreak())
1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    IPC_END_MESSAGE_MAP()
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnChannelError() OVERRIDE {
174f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    DVLOG(1) << "Channel error. Exiting.";
175a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    ui_proxy_->PostTask(FROM_HERE,
176a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        base::Bind(&ChromeAppViewAsh::OnMetroExit, base::Unretained(app_view_),
177a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                   TERMINATE_USING_KEY_SEQUENCE));
178a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
179f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // In early Windows 8 versions the code above sometimes fails so we call
180f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // it a second time with a NULL window which just calls Exit().
181f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    ui_proxy_->PostDelayedTask(FROM_HERE,
182a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        base::Bind(&ChromeAppViewAsh::OnMetroExit, base::Unretained(app_view_),
183a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                   TERMINATE_USING_PROCESS_EXIT),
184f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        base::TimeDelta::FromMilliseconds(100));
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
188a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  void OnActivateDesktop(const base::FilePath& shortcut, bool ash_exit) {
1890f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    ui_proxy_->PostTask(FROM_HERE,
1900f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        base::Bind(&ChromeAppViewAsh::OnActivateDesktop,
1910f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        base::Unretained(app_view_),
192a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        shortcut, ash_exit));
1930f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  }
1940f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
1955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void OnMetroExit() {
196a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    ui_proxy_->PostTask(FROM_HERE,
197a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        base::Bind(&ChromeAppViewAsh::OnMetroExit,
198a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        base::Unretained(app_view_), TERMINATE_USING_KEY_SEQUENCE));
1995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
2005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
20158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  void OnOpenURLOnDesktop(const base::FilePath& shortcut,
2025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                          const base::string16& url) {
20358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    ui_proxy_->PostTask(FROM_HERE,
20458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        base::Bind(&ChromeAppViewAsh::OnOpenURLOnDesktop,
20558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        base::Unretained(app_view_),
20658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        shortcut, url));
20758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
20858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void OnSetCursor(int64 cursor) {
2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ui_proxy_->PostTask(FROM_HERE,
2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                        base::Bind(&ChromeAppViewAsh::OnSetCursor,
2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                   base::Unretained(app_view_),
2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                   reinterpret_cast<HCURSOR>(cursor)));
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void OnDisplayFileOpenDialog(const base::string16& title,
2175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                               const base::string16& filter,
218c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                               const base::FilePath& default_path,
2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                               bool allow_multiple_files) {
2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ui_proxy_->PostTask(FROM_HERE,
2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                        base::Bind(&ChromeAppViewAsh::OnDisplayFileOpenDialog,
2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                   base::Unretained(app_view_),
2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                   title,
2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                   filter,
2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                   default_path,
2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                   allow_multiple_files));
2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void OnDisplayFileSaveAsDialog(
2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const MetroViewerHostMsg_SaveAsDialogParams& params) {
2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ui_proxy_->PostTask(
2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        FROM_HERE,
2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        base::Bind(&ChromeAppViewAsh::OnDisplayFileSaveAsDialog,
2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   base::Unretained(app_view_),
2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   params));
2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void OnDisplayFolderPicker(const base::string16& title) {
239c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ui_proxy_->PostTask(
240c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        FROM_HERE,
241c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        base::Bind(&ChromeAppViewAsh::OnDisplayFolderPicker,
242c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                   base::Unretained(app_view_),
243c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                   title));
244c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
245c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
246b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  void OnSetCursorPos(int x, int y) {
247b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    VLOG(1) << "In IPC OnSetCursorPos: " << x << ", " << y;
248b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    ui_proxy_->PostTask(
249b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        FROM_HERE,
250b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        base::Bind(&ChromeAppViewAsh::OnSetCursorPos,
251b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                   base::Unretained(app_view_),
252b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                   x, y));
253b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  }
254b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
255a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  void OnImeCancelComposition() {
256a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    ui_proxy_->PostTask(
257a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        FROM_HERE,
258a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        base::Bind(&ChromeAppViewAsh::OnImeCancelComposition,
259a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                   base::Unretained(app_view_)));
260a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
261a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
262a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  void OnImeTextInputClientChanged(
263a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      const std::vector<int32>& input_scopes,
264a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      const std::vector<metro_viewer::CharacterBounds>& character_bounds) {
265a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    ui_proxy_->PostTask(
266a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        FROM_HERE,
267a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        base::Bind(&ChromeAppViewAsh::OnImeUpdateTextInputClient,
268a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                   base::Unretained(app_view_),
269a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                   input_scopes,
270a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                   character_bounds));
271a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
272b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<base::MessageLoopProxy> ui_proxy_;
2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ChromeAppViewAsh* app_view_;
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void RunMessageLoop(winui::Core::ICoreDispatcher* dispatcher) {
2785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // We're entering a nested message loop, let's allow dispatching
2795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // tasks while we're in there.
2805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::MessageLoop::current()->SetNestableTasksAllowed(true);
2815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Enter main core message loop. There are several ways to exit it
2835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Nicely:
2845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // 1 - User action like ALT-F4.
2855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // 2 - Calling ICoreApplicationExit::Exit().
2865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // 3-  Posting WM_CLOSE to the core window.
2875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  HRESULT hr = dispatcher->ProcessEvents(
2885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      winui::Core::CoreProcessEventsOption
2895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          ::CoreProcessEventsOption_ProcessUntilQuit);
2905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Wind down the thread's chrome message loop.
2925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::MessageLoop::current()->Quit();
2935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
2945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Helper to return the state of the shift/control/alt keys.
2965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)uint32 GetKeyboardEventFlags() {
2975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  uint32 flags = 0;
2985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (base::win::IsShiftPressed())
2995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    flags |= ui::EF_SHIFT_DOWN;
3005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (base::win::IsCtrlPressed())
3015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    flags |= ui::EF_CONTROL_DOWN;
3025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (base::win::IsAltPressed())
3035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    flags |= ui::EF_ALT_DOWN;
3045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return flags;
3055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool LaunchChromeBrowserProcess(const wchar_t* additional_parameters,
3085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                winapp::Activation::IActivatedEventArgs* args) {
3095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (args) {
3105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    DVLOG(1) << __FUNCTION__ << ":" << ::GetCommandLineW();
3115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    winapp::Activation::ActivationKind activation_kind;
3125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    CheckHR(args->get_Kind(&activation_kind));
3135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    DVLOG(1) << __FUNCTION__ << ", activation_kind=" << activation_kind;
3155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (activation_kind == winapp::Activation::ActivationKind_Launch) {
3175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      mswr::ComPtr<winapp::Activation::ILaunchActivatedEventArgs> launch_args;
3185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      if (args->QueryInterface(
3195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)              winapp::Activation::IID_ILaunchActivatedEventArgs,
3205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)              &launch_args) == S_OK) {
3215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        DVLOG(1) << "Activate: ActivationKind_Launch";
3225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        mswrw::HString launch_args_str;
3235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        launch_args->get_Arguments(launch_args_str.GetAddressOf());
3245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        base::string16 actual_launch_args(
3255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            MakeStdWString(launch_args_str.Get()));
3265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        if (actual_launch_args == win8::kMetroViewerConnectVerb) {
3275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          DVLOG(1) << __FUNCTION__ << "Not launching chrome server";
3285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          return true;
3295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        }
3305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      }
3315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
3325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
3335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DVLOG(1) << "Launching chrome server";
3355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::FilePath chrome_exe_path;
3365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!PathService::Get(base::FILE_EXE, &chrome_exe_path))
3385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return false;
3395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  base::string16 parameters = L"--silent-launch --connect-to-metro-viewer ";
3415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (additional_parameters)
3425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    parameters += additional_parameters;
3435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SHELLEXECUTEINFO sei = { sizeof(sei) };
3455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  sei.nShow = SW_SHOWNORMAL;
3465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  sei.lpFile = chrome_exe_path.value().c_str();
3475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  sei.lpDirectory = L"";
3485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  sei.lpParameters = parameters.c_str();
3495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ::ShellExecuteEx(&sei);
3505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return true;
3515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}  // namespace
3545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This class helps decoding the pointer properties of an event.
3565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class ChromeAppViewAsh::PointerInfoHandler {
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
358cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  PointerInfoHandler(float metro_dpi_scale, float win32_dpi_scale)
3598bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      : x_(0),
3608bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)        y_(0),
3618bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)        wheel_delta_(0),
3628bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)        update_kind_(winui::Input::PointerUpdateKind_Other),
3638bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)        timestamp_(0),
3645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        pointer_id_(0),
3655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        mouse_down_flags_(0),
366cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        is_horizontal_wheel_(0),
367cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        metro_dpi_scale_(metro_dpi_scale),
368cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        win32_dpi_scale_(win32_dpi_scale) {}
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HRESULT Init(winui::Core::IPointerEventArgs* args) {
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HRESULT hr = args->get_CurrentPoint(&pointer_point_);
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (FAILED(hr))
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return hr;
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    winfoundtn::Point point;
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    hr = pointer_point_->get_Position(&point);
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (FAILED(hr))
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return hr;
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mswr::ComPtr<winui::Input::IPointerPointProperties> properties;
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    hr = pointer_point_->get_Properties(&properties);
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (FAILED(hr))
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return hr;
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    hr = properties->get_PointerUpdateKind(&update_kind_);
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (FAILED(hr))
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return hr;
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    hr = properties->get_MouseWheelDelta(&wheel_delta_);
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (FAILED(hr))
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return hr;
3925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    is_horizontal_wheel_ = 0;
3945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    properties->get_IsHorizontalMouseWheel(&is_horizontal_wheel_);
3955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
396cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // The input coordinates are in DIP based on the metro scale factor.
397cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // We want to convert it to DIP based on the win32 scale factor.
398cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // We scale the point by the metro scale factor and then scale down
399cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // via the win32 scale factor which achieves the needful.
400cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    gfx::Point dip_point_metro(point.X, point.Y);
401cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    gfx::Point scaled_point_metro =
402cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      gfx::ToCeiledPoint(gfx::ScalePoint(dip_point_metro, metro_dpi_scale_));
403cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    gfx::Point dip_point_win32 =
404cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        gfx::ToCeiledPoint(gfx::ScalePoint(scaled_point_metro,
405cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                           1.0 / win32_dpi_scale_));
406cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    x_ = dip_point_win32.x();
407cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    y_ = dip_point_win32.y();
4085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    pointer_point_->get_Timestamp(&timestamp_);
410c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    pointer_point_->get_PointerId(&pointer_id_);
411c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // Map the OS touch event id to a range allowed by the gesture recognizer.
412c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (IsTouch())
4131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      pointer_id_ %= ui::MotionEvent::MAX_TOUCH_POINT_COUNT;
4145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    boolean left_button_state;
4165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    hr = properties->get_IsLeftButtonPressed(&left_button_state);
4175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (FAILED(hr))
4185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return hr;
4195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (left_button_state)
4205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      mouse_down_flags_ |= ui::EF_LEFT_MOUSE_BUTTON;
4215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    boolean right_button_state;
4235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    hr = properties->get_IsRightButtonPressed(&right_button_state);
4245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (FAILED(hr))
4255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return hr;
4265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (right_button_state)
4275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      mouse_down_flags_ |= ui::EF_RIGHT_MOUSE_BUTTON;
4285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    boolean middle_button_state;
4305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    hr = properties->get_IsMiddleButtonPressed(&middle_button_state);
4315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (FAILED(hr))
4325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return hr;
4335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (middle_button_state)
4345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      mouse_down_flags_ |= ui::EF_MIDDLE_MOUSE_BUTTON;
4355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return S_OK;
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool IsType(windevs::Input::PointerDeviceType type) const {
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mswr::ComPtr<windevs::Input::IPointerDevice> pointer_device;
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CheckHR(pointer_point_->get_PointerDevice(&pointer_device));
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    windevs::Input::PointerDeviceType device_type;
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CheckHR(pointer_device->get_PointerDeviceType(&device_type));
4442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return  (device_type == type);
4452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool IsMouse() const {
4482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return IsType(windevs::Input::PointerDeviceType_Mouse);
4492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool IsTouch() const {
4522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return IsType(windevs::Input::PointerDeviceType_Touch);
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int32 wheel_delta() const {
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return wheel_delta_;
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Identifies the button that changed.
4605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ui::EventFlags changed_button() const {
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    switch (update_kind_) {
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case winui::Input::PointerUpdateKind_LeftButtonPressed:
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return ui::EF_LEFT_MOUSE_BUTTON;
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case winui::Input::PointerUpdateKind_LeftButtonReleased:
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return ui::EF_LEFT_MOUSE_BUTTON;
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case winui::Input::PointerUpdateKind_RightButtonPressed:
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return ui::EF_RIGHT_MOUSE_BUTTON;
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case winui::Input::PointerUpdateKind_RightButtonReleased:
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return ui::EF_RIGHT_MOUSE_BUTTON;
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case winui::Input::PointerUpdateKind_MiddleButtonPressed:
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return ui::EF_MIDDLE_MOUSE_BUTTON;
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case winui::Input::PointerUpdateKind_MiddleButtonReleased:
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return ui::EF_MIDDLE_MOUSE_BUTTON;
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      default:
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return ui::EF_NONE;
4765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  uint32 mouse_down_flags() const { return mouse_down_flags_; }
4805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int x() const { return x_; }
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int y() const { return y_; }
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
484c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  uint32 pointer_id() const {
485c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return pointer_id_;
486c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
487c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
4882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  uint64 timestamp() const { return timestamp_; }
4892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  winui::Input::PointerUpdateKind update_kind() const { return update_kind_; }
4915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool is_horizontal_wheel() const { return !!is_horizontal_wheel_; }
4935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int x_;
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int y_;
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int wheel_delta_;
498c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  uint32 pointer_id_;
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  winui::Input::PointerUpdateKind update_kind_;
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mswr::ComPtr<winui::Input::IPointerPoint> pointer_point_;
5012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  uint64 timestamp_;
50268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
5035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Bitmask of ui::EventFlags corresponding to the buttons that are currently
5045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // down.
5055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  uint32 mouse_down_flags_;
50668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
5075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Set to true for a horizontal wheel message.
5085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  boolean is_horizontal_wheel_;
50968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
510cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // The metro device scale factor as reported by the winrt interfaces.
511cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  float metro_dpi_scale_;
512cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // The win32 dpi scale which is queried via GetDeviceCaps. Please refer to
513cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // ui/gfx/win/dpi.cc for more information.
514cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  float win32_dpi_scale_;
515cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
5165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(PointerInfoHandler);
5175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)};
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ChromeAppViewAsh::ChromeAppViewAsh()
520c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    : mouse_down_flags_(ui::EF_NONE),
521c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      ui_channel_(nullptr),
522cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      core_window_hwnd_(NULL),
523cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      metro_dpi_scale_(0),
5241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      win32_dpi_scale_(0),
5251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      last_cursor_(NULL),
5261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      channel_listener_(NULL) {
527868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DVLOG(1) << __FUNCTION__;
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  globals.previous_state =
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      winapp::Activation::ApplicationExecutionState_NotRunning;
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ChromeAppViewAsh::~ChromeAppViewAsh() {
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DVLOG(1) << __FUNCTION__;
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IFACEMETHODIMP
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ChromeAppViewAsh::Initialize(winapp::Core::ICoreApplicationView* view) {
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  view_ = view;
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DVLOG(1) << __FUNCTION__;
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HRESULT hr = view_->add_Activated(mswr::Callback<ActivatedHandler>(
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      this, &ChromeAppViewAsh::OnActivate).Get(),
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &activated_token_);
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CheckHR(hr);
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return hr;
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IFACEMETHODIMP
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ChromeAppViewAsh::SetWindow(winui::Core::ICoreWindow* window) {
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window_ = window;
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DVLOG(1) << __FUNCTION__;
551c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
552c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Retrieve the native window handle via the interop layer.
553c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  mswr::ComPtr<ICoreWindowInterop> interop;
554c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  HRESULT hr = window->QueryInterface(interop.GetAddressOf());
555c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CheckHR(hr);
556c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  hr = interop->get_WindowHandle(&core_window_hwnd_);
557c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CheckHR(hr);
558c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
559a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  text_service_ = metro_driver::CreateTextService(this, core_window_hwnd_);
560a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
5617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  hr = window_->add_SizeChanged(mswr::Callback<SizeChangedHandler>(
5627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      this, &ChromeAppViewAsh::OnSizeChanged).Get(),
5637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      &sizechange_token_);
5647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  CheckHR(hr);
5657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Register for pointer and keyboard notifications. We forward
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // them to the browser process via IPC.
568c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  hr = window_->add_PointerMoved(mswr::Callback<PointerEventHandler>(
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      this, &ChromeAppViewAsh::OnPointerMoved).Get(),
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &pointermoved_token_);
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CheckHR(hr);
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  hr = window_->add_PointerPressed(mswr::Callback<PointerEventHandler>(
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      this, &ChromeAppViewAsh::OnPointerPressed).Get(),
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &pointerpressed_token_);
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CheckHR(hr);
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  hr = window_->add_PointerReleased(mswr::Callback<PointerEventHandler>(
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      this, &ChromeAppViewAsh::OnPointerReleased).Get(),
5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &pointerreleased_token_);
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CheckHR(hr);
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  hr = window_->add_KeyDown(mswr::Callback<KeyEventHandler>(
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      this, &ChromeAppViewAsh::OnKeyDown).Get(),
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &keydown_token_);
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CheckHR(hr);
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  hr = window_->add_KeyUp(mswr::Callback<KeyEventHandler>(
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      this, &ChromeAppViewAsh::OnKeyUp).Get(),
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &keyup_token_);
5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CheckHR(hr);
5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  mswr::ComPtr<winui::Core::ICoreDispatcher> dispatcher;
594effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  hr = window_->get_Dispatcher(dispatcher.GetAddressOf());
5952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CheckHR(hr, "Get Dispatcher failed.");
5962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  mswr::ComPtr<winui::Core::ICoreAcceleratorKeys> accelerator_keys;
5982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  hr = dispatcher.CopyTo(__uuidof(winui::Core::ICoreAcceleratorKeys),
5992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         reinterpret_cast<void**>(
6002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            accelerator_keys.GetAddressOf()));
6012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CheckHR(hr, "QI for ICoreAcceleratorKeys failed.");
6022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  hr = accelerator_keys->add_AcceleratorKeyActivated(
6032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      mswr::Callback<AcceleratorKeyEventHandler>(
6042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          this, &ChromeAppViewAsh::OnAcceleratorKeyDown).Get(),
6052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      &accel_keydown_token_);
6062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CheckHR(hr);
6072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  hr = window_->add_PointerWheelChanged(mswr::Callback<PointerEventHandler>(
6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      this, &ChromeAppViewAsh::OnWheel).Get(),
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &wheel_token_);
6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CheckHR(hr);
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  hr = window_->add_CharacterReceived(mswr::Callback<CharEventHandler>(
6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      this, &ChromeAppViewAsh::OnCharacterReceived).Get(),
6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &character_received_token_);
6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CheckHR(hr);
6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
618c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  hr = window_->add_Activated(mswr::Callback<WindowActivatedHandler>(
619c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      this, &ChromeAppViewAsh::OnWindowActivated).Get(),
620c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      &window_activated_token_);
621c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CheckHR(hr);
622c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
623effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  if (base::win::GetVersion() >= base::win::VERSION_WIN8) {
624effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    // Register for edge gesture notifications only for Windows 8 and above.
625effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    mswr::ComPtr<winui::Input::IEdgeGestureStatics> edge_gesture_statics;
626effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    hr = winrt_utils::CreateActivationFactory(
627effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        RuntimeClass_Windows_UI_Input_EdgeGesture,
628effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        edge_gesture_statics.GetAddressOf());
629effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    CheckHR(hr);
630effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
631effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    mswr::ComPtr<winui::Input::IEdgeGesture> edge_gesture;
632effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    hr = edge_gesture_statics->GetForCurrentView(&edge_gesture);
633effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    CheckHR(hr);
634effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
635effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    hr = edge_gesture->add_Completed(mswr::Callback<EdgeEventHandler>(
636effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        this, &ChromeAppViewAsh::OnEdgeGestureCompleted).Get(),
637effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        &edgeevent_token_);
638effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    CheckHR(hr);
639effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  }
640f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // By initializing the direct 3D swap chain with the corewindow
6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // we can now directly blit to it from the browser process.
6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  direct3d_helper_.Initialize(window);
6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DVLOG(1) << "Initialized Direct3D.";
645cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
646cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // On Windows 8+ the WinRT interface IDisplayProperties which we use to get
647cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // device scale factor does not return the correct values in metro mode.
648cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // To workaround this we retrieve the device scale factor via the win32 way
649cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // and scale input coordinates accordingly to pass them in DIP to chrome.
650cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // TODO(ananta). Investigate and fix.
651cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  metro_dpi_scale_ = GetModernUIScale();
652cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  win32_dpi_scale_ = gfx::GetDPIScale();
653cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DVLOG(1) << "Metro Scale is " << metro_dpi_scale_;
654cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DVLOG(1) << "Win32 Scale is " << win32_dpi_scale_;
6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return S_OK;
6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IFACEMETHODIMP
6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ChromeAppViewAsh::Load(HSTRING entryPoint) {
660effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // On Win7 |entryPoint| is NULL.
6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DVLOG(1) << __FUNCTION__;
6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return S_OK;
6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IFACEMETHODIMP
6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ChromeAppViewAsh::Run() {
6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DVLOG(1) << __FUNCTION__;
6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mswr::ComPtr<winui::Core::ICoreDispatcher> dispatcher;
669effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  HRESULT hr = window_->get_Dispatcher(dispatcher.GetAddressOf());
6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CheckHR(hr, "Dispatcher failed.");
6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create the IPC channel IO thread. It needs to out-live the ChannelProxy.
6731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  io_thread_.reset(new base::Thread("metro_IO_thread"));
6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::Thread::Options options;
675c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  options.message_loop_type = base::MessageLoop::TYPE_IO;
6761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  io_thread_->StartWithOptions(options);
6772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
678868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ChromeChannelListener ui_channel_listener(&ui_loop_, this);
6791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  channel_listener_ = &ui_channel_listener;
680a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
6811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // We can't do anything until the Chrome browser IPC channel is initialized.
6821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Lazy initialization in a timer.
6831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ui_loop_.PostDelayedTask(FROM_HERE,
6841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      base::Bind(base::IgnoreResult(&ChromeAppViewAsh::StartChromeOSMode),
6851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                 base::Unretained(this)),
6861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      base::TimeDelta::FromMilliseconds(kChromeChannelPollTimerMs));
6875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
6881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Post the task that'll do the inner Metro message pumping to it.
689868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ui_loop_.PostTask(FROM_HERE, base::Bind(&RunMessageLoop, dispatcher.Get()));
690868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ui_loop_.Run();
6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  io_thread_.reset(NULL);
6931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ui_channel_.reset(NULL);
6941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  channel_listener_ = NULL;
6951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DVLOG(0) << "ProcessEvents done, hr=" << hr;
6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return hr;
6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IFACEMETHODIMP
7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ChromeAppViewAsh::Uninitialize() {
7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DVLOG(1) << __FUNCTION__;
7035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  metro_driver::RemoveImePopupObserver(this);
704a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  input_source_.reset();
705a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  text_service_.reset();
7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window_ = nullptr;
7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  view_ = nullptr;
708c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  core_window_hwnd_ = NULL;
7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return S_OK;
7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static
7132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)HRESULT ChromeAppViewAsh::Unsnap() {
7142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  mswr::ComPtr<winui::ViewManagement::IApplicationViewStatics> view_statics;
7152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  HRESULT hr = winrt_utils::CreateActivationFactory(
7162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      RuntimeClass_Windows_UI_ViewManagement_ApplicationView,
7172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      view_statics.GetAddressOf());
7182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CheckHR(hr);
7192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  winui::ViewManagement::ApplicationViewState state =
7212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      winui::ViewManagement::ApplicationViewState_FullScreenLandscape;
7222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  hr = view_statics->get_Value(&state);
7232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CheckHR(hr);
7242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (state == winui::ViewManagement::ApplicationViewState_Snapped) {
7262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    boolean success = FALSE;
7272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    hr = view_statics->TryUnsnap(&success);
7282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (FAILED(hr) || !success) {
7302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      LOG(ERROR) << "Failed to unsnap. Error 0x" << hr;
7312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (SUCCEEDED(hr))
7322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        hr = E_UNEXPECTED;
7332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
7342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
7352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return hr;
7362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
738a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void ChromeAppViewAsh::OnActivateDesktop(const base::FilePath& file_path,
739a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                         bool ash_exit) {
740a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  DVLOG(1) << "ChannelAppViewAsh::OnActivateDesktop\n";
741f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
742a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (ash_exit) {
743a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    // As we are the top level window, the exiting is done async so we manage
744a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    // to execute  the entire function including the final Send().
745a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    OnMetroExit(TERMINATE_USING_KEY_SEQUENCE);
746a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
747f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
7480f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // We are just executing delegate_execute here without parameters. Assumption
7490f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // here is that this process will be reused by shell when asking for
7500f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // IExecuteCommand interface.
7510f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
7520f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // TODO(shrikant): Consolidate ShellExecuteEx with SEE_MASK_FLAG_LOG_USAGE
7530f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // and place it metro.h or similar accessible file from all code code paths
7540f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // using this function.
7550f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  SHELLEXECUTEINFO sei = { sizeof(sei) };
7560f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  sei.fMask = SEE_MASK_FLAG_LOG_USAGE;
7570f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  sei.nShow = SW_SHOWNORMAL;
7580f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  sei.lpFile = file_path.value().c_str();
7590f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  sei.lpParameters = NULL;
760a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (!ash_exit)
761a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    sei.fMask |= SEE_MASK_NOCLOSEPROCESS;
7620f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  ::ShellExecuteExW(&sei);
763a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (!ash_exit) {
764a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    ::TerminateProcess(sei.hProcess, 0);
765a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    ::CloseHandle(sei.hProcess);
766a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
7670f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)}
7682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
76958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void ChromeAppViewAsh::OnOpenURLOnDesktop(const base::FilePath& shortcut,
7705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                          const base::string16& url) {
77158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  base::FilePath::StringType file = shortcut.value();
77258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  SHELLEXECUTEINFO sei = { sizeof(sei) };
77358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  sei.fMask = SEE_MASK_FLAG_LOG_USAGE;
77458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  sei.nShow = SW_SHOWNORMAL;
77558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  sei.lpFile = file.c_str();
77658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  sei.lpDirectory = L"";
77758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  sei.lpParameters = url.c_str();
77858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  BOOL result = ShellExecuteEx(&sei);
77958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
78058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
7812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ChromeAppViewAsh::OnSetCursor(HCURSOR cursor) {
7821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ::SetCursor(cursor);
7831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  last_cursor_ = cursor;
7842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
786c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void ChromeAppViewAsh::OnDisplayFileOpenDialog(
7875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const base::string16& title,
7885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const base::string16& filter,
789c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const base::FilePath& default_path,
790c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    bool allow_multiple_files) {
7912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DVLOG(1) << __FUNCTION__;
7922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The OpenFilePickerSession instance is deleted when we receive a
7942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // callback from the OpenFilePickerSession class about the completion of the
7952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // operation.
796c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  FilePickerSessionBase* file_picker_ =
7972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new OpenFilePickerSession(this,
7982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                title,
7992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                filter,
8007dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                default_path,
8012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                allow_multiple_files);
802c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  file_picker_->Run();
8032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
8042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ChromeAppViewAsh::OnDisplayFileSaveAsDialog(
8062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const MetroViewerHostMsg_SaveAsDialogParams& params) {
8072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DVLOG(1) << __FUNCTION__;
8082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The SaveFilePickerSession instance is deleted when we receive a
810c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // callback from the SaveFilePickerSession class about the completion of the
8112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // operation.
812c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  FilePickerSessionBase* file_picker_ =
8132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new SaveFilePickerSession(this, params);
814c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  file_picker_->Run();
815c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
816c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
8175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ChromeAppViewAsh::OnDisplayFolderPicker(const base::string16& title) {
818c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DVLOG(1) << __FUNCTION__;
819c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // The FolderPickerSession instance is deleted when we receive a
820c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // callback from the FolderPickerSession class about the completion of the
821c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // operation.
822c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  FilePickerSessionBase* file_picker_ = new FolderPickerSession(this, title);
823c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  file_picker_->Run();
8242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
8252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
826b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)void ChromeAppViewAsh::OnSetCursorPos(int x, int y) {
827b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  if (ui_channel_) {
828b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    ::SetCursorPos(x, y);
829b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    DVLOG(1) << "In UI OnSetCursorPos: " << x << ", " << y;
830b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    ui_channel_->Send(new MetroViewerHostMsg_SetCursorPosAck());
831b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    // Generate a fake mouse move which matches the SetCursor coordinates as
832b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    // the browser expects to receive a mouse move for these coordinates.
833b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    // It is not clear why we don't receive a real mouse move in response to
834b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    // the SetCursorPos calll above.
835b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    ui_channel_->Send(new MetroViewerHostMsg_MouseMoved(x, y, 0));
836b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  }
837b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)}
838b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
8392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ChromeAppViewAsh::OnOpenFileCompleted(
8402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    OpenFilePickerSession* open_file_picker,
8412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool success) {
8422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DVLOG(1) << __FUNCTION__;
8432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DVLOG(1) << "Success: " << success;
8442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (ui_channel_) {
8452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (open_file_picker->allow_multi_select()) {
8462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ui_channel_->Send(new MetroViewerHostMsg_MultiFileOpenDone(
8472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          success, open_file_picker->filenames()));
8482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
8492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ui_channel_->Send(new MetroViewerHostMsg_FileOpenDone(
850c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          success, base::FilePath(open_file_picker->result())));
8512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
8522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
8532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  delete open_file_picker;
8542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
8552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ChromeAppViewAsh::OnSaveFileCompleted(
8572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SaveFilePickerSession* save_file_picker,
8582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool success) {
8592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DVLOG(1) << __FUNCTION__;
8602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DVLOG(1) << "Success: " << success;
8612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (ui_channel_) {
8622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ui_channel_->Send(new MetroViewerHostMsg_FileSaveAsDone(
8632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        success,
864c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        base::FilePath(save_file_picker->result()),
8652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        save_file_picker->filter_index()));
8662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
8672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  delete save_file_picker;
8682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
8692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
870c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void ChromeAppViewAsh::OnFolderPickerCompleted(
871c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    FolderPickerSession* folder_picker,
872c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    bool success) {
873c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DVLOG(1) << __FUNCTION__;
874c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DVLOG(1) << "Success: " << success;
875c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (ui_channel_) {
876c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ui_channel_->Send(new MetroViewerHostMsg_SelectFolderDone(
877c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        success,
878c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        base::FilePath(folder_picker->result())));
879c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
880c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  delete folder_picker;
881c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
882c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
883a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void ChromeAppViewAsh::OnImeCancelComposition() {
884a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (!text_service_)
885a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    return;
886a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  text_service_->CancelComposition();
887a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
888a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
889a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void ChromeAppViewAsh::OnImeUpdateTextInputClient(
890a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    const std::vector<int32>& input_scopes,
891a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    const std::vector<metro_viewer::CharacterBounds>& character_bounds) {
892a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (!text_service_)
893a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    return;
894a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  text_service_->OnDocumentChanged(input_scopes, character_bounds);
895a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
896a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
8975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ChromeAppViewAsh::OnImePopupChanged(ImePopupObserver::EventType event) {
8985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!ui_channel_)
8995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return;
9005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  switch (event) {
9015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    case ImePopupObserver::kPopupShown:
9025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      ui_channel_->Send(new MetroViewerHostMsg_ImeCandidatePopupChanged(true));
9035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return;
9045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    case ImePopupObserver::kPopupHidden:
9055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      ui_channel_->Send(new MetroViewerHostMsg_ImeCandidatePopupChanged(false));
9065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return;
9075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    case ImePopupObserver::kPopupUpdated:
9085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      // TODO(kochi): Support this event for W3C IME API proposal.
9095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      // See crbug.com/238585.
9105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return;
9115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    default:
9125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      NOTREACHED() << "unknown event type: " << event;
9135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return;
9145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
9155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
9165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
917a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Function to Exit metro chrome cleanly. If we are in the foreground
918a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// then we try and exit by sending an Alt+F4 key combination to the core
919a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// window which ensures that the chrome application tile does not show up in
920a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// the running metro apps list on the top left corner.
921a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void ChromeAppViewAsh::OnMetroExit(MetroTerminateMethod method) {
9220529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (base::win::GetVersion() >= base::win::VERSION_WIN8) {
9230529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    HWND core_window = core_window_hwnd();
9240529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    if (method == TERMINATE_USING_KEY_SEQUENCE && core_window != NULL &&
9250529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        core_window == ::GetForegroundWindow()) {
9260529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      DVLOG(1) << "We are in the foreground. Exiting via Alt F4";
9270529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      SendKeySequence(VK_F4, ALT);
928cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      if (ui_channel_)
929cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        ui_channel_->Close();
930cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    } else {
931cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      globals.app_exit->Exit();
9320529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    }
933cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  } else {
934cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (ui_channel_)
935cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      ui_channel_->Close();
9360529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
9371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    HWND core_window = core_window_hwnd();
9381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    ::PostMessage(core_window, WM_CLOSE, 0, 0);
9391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
940cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    globals.app_exit->Exit();
941cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
942a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
943a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
944a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void ChromeAppViewAsh::OnInputSourceChanged() {
945a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (!input_source_)
946a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    return;
947a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
9481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK(ui_channel_);
9491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
950a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  LANGID langid = 0;
951a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  bool is_ime = false;
952a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (!input_source_->GetActiveSource(&langid, &is_ime)) {
953a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    LOG(ERROR) << "GetActiveSource failed";
954a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    return;
955a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
956a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ui_channel_->Send(new MetroViewerHostMsg_ImeInputSourceChanged(langid,
957a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                                                 is_ime));
958a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
959a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
960a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void ChromeAppViewAsh::OnCompositionChanged(
9615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const base::string16& text,
962a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    int32 selection_start,
963a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    int32 selection_end,
964a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    const std::vector<metro_viewer::UnderlineInfo>& underlines) {
965a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ui_channel_->Send(new MetroViewerHostMsg_ImeCompositionChanged(
966a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      text, selection_start, selection_end, underlines));
967a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
968a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
9695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ChromeAppViewAsh::OnTextCommitted(const base::string16& text) {
970a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ui_channel_->Send(new MetroViewerHostMsg_ImeTextCommitted(text));
971a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
972a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
9735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ChromeAppViewAsh::SendMouseButton(int x,
9745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                       int y,
9755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                       int extra,
9765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                       ui::EventType event_type,
9775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                       uint32 flags,
9785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                       ui::EventFlags changed_button,
9795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                       bool is_horizontal_wheel) {
9801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!ui_channel_)
9811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return;
9825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  MetroViewerHostMsg_MouseButtonParams params;
9835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  params.x = static_cast<int32>(x);
9845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  params.y = static_cast<int32>(y);
9855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  params.extra = static_cast<int32>(extra);
9865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  params.event_type = event_type;
9875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  params.flags = static_cast<int32>(flags);
9885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  params.changed_button = changed_button;
9895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  params.is_horizontal_wheel = is_horizontal_wheel;
9905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ui_channel_->Send(new MetroViewerHostMsg_MouseButton(params));
9915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
9925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
9935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ChromeAppViewAsh::GenerateMouseEventFromMoveIfNecessary(
9945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const PointerInfoHandler& pointer) {
9955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ui::EventType event_type;
9965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // For aura we want the flags to include the button that was released, thus
9975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // we or the old and new.
9985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  uint32 mouse_down_flags = pointer.mouse_down_flags() | mouse_down_flags_;
9995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  mouse_down_flags_ = pointer.mouse_down_flags();
10005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  switch (pointer.update_kind()) {
10015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    case winui::Input::PointerUpdateKind_LeftButtonPressed:
10025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    case winui::Input::PointerUpdateKind_RightButtonPressed:
10035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    case winui::Input::PointerUpdateKind_MiddleButtonPressed:
10045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      event_type = ui::ET_MOUSE_PRESSED;
10055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      break;
10065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    case winui::Input::PointerUpdateKind_LeftButtonReleased:
10075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    case winui::Input::PointerUpdateKind_RightButtonReleased:
10085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    case winui::Input::PointerUpdateKind_MiddleButtonReleased:
10095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      event_type = ui::ET_MOUSE_RELEASED;
10105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      break;
10115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    default:
10125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return;
10135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
10145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SendMouseButton(pointer.x(), pointer.y(), 0, event_type,
10155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                  mouse_down_flags | GetKeyboardEventFlags(),
10165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                  pointer.changed_button(), pointer.is_horizontal_wheel());
10175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
10185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
10192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)HRESULT ChromeAppViewAsh::OnActivate(
10202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    winapp::Core::ICoreApplicationView*,
10215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    winapp::Activation::IActivatedEventArgs* args) {
10225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DVLOG(1) << __FUNCTION__;
1023c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Note: If doing more work in this function, you migth need to call
1024c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // get_PreviousExecutionState() and skip the work if  the result is
1025c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // ApplicationExecutionState_Running and globals.previous_state is too.
10265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  args->get_PreviousExecutionState(&globals.previous_state);
10275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DVLOG(1) << "Previous Execution State: " << globals.previous_state;
10285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1029868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  winapp::Activation::ActivationKind activation_kind;
1030868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  CheckHR(args->get_Kind(&activation_kind));
103168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  DVLOG(1) << "Activation kind: " << activation_kind;
103268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
1033868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (activation_kind == winapp::Activation::ActivationKind_Search)
1034868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    HandleSearchRequest(args);
1035868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  else if (activation_kind == winapp::Activation::ActivationKind_Protocol)
1036868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    HandleProtocolRequest(args);
103768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  else
1038f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    LaunchChromeBrowserProcess(NULL, args);
1039868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // We call ICoreWindow::Activate after the handling for the search/protocol
1040868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // requests because Chrome can be launched to handle a search request which
1041868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // in turn launches the chrome browser process in desktop mode via
1042868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // ShellExecute. If we call ICoreWindow::Activate before this, then
1043868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Windows kills the metro chrome process when it calls ShellExecute. Seems
1044868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // to be a bug.
10455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window_->Activate();
10465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return S_OK;
10475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HRESULT ChromeAppViewAsh::OnPointerMoved(winui::Core::ICoreWindow* sender,
10502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                         winui::Core::IPointerEventArgs* args) {
10511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!ui_channel_)
10521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return S_OK;
10531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1054cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  PointerInfoHandler pointer(metro_dpi_scale_, win32_dpi_scale_);
10555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HRESULT hr = pointer.Init(args);
10565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (FAILED(hr))
10575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return hr;
10585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (pointer.IsMouse()) {
10601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // If the mouse was moved towards the charms or the OS specific section,
10611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // the cursor may change from what the browser last set. Restore it here.
10621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    if (::GetCursor() != last_cursor_)
10631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      SetCursor(last_cursor_);
10641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
10655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    GenerateMouseEventFromMoveIfNecessary(pointer);
10663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    ui_channel_->Send(new MetroViewerHostMsg_MouseMoved(
10673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        pointer.x(),
10683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        pointer.y(),
10693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        mouse_down_flags_ | GetKeyboardEventFlags()));
10702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
10712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DCHECK(pointer.IsTouch());
10722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ui_channel_->Send(new MetroViewerHostMsg_TouchMoved(pointer.x(),
10732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                        pointer.y(),
1074c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                                        pointer.timestamp(),
1075c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                                        pointer.pointer_id()));
10762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
10775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return S_OK;
10785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// NOTE: From experimentation, it seems like Metro only sends a PointerPressed
10812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// event for the first button pressed and the last button released in a sequence
10822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// of mouse events.
10832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// For example, a sequence of LEFT_DOWN, RIGHT_DOWN, LEFT_UP, RIGHT_UP results
10845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// only in PointerPressed(LEFT)/PointerReleased(RIGHT) events. Intermediary
10855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// presses and releases are tracked in OnPointMoved().
10862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)HRESULT ChromeAppViewAsh::OnPointerPressed(
10872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    winui::Core::ICoreWindow* sender,
10885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    winui::Core::IPointerEventArgs* args) {
10891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!ui_channel_)
10901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return S_OK;
10911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1092cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  PointerInfoHandler pointer(metro_dpi_scale_, win32_dpi_scale_);
10935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HRESULT hr = pointer.Init(args);
10945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (FAILED(hr))
10955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return hr;
10962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (pointer.IsMouse()) {
10985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    mouse_down_flags_ = pointer.mouse_down_flags();
10995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    SendMouseButton(pointer.x(), pointer.y(), 0, ui::ET_MOUSE_PRESSED,
11005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                    mouse_down_flags_ | GetKeyboardEventFlags(),
11015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                    pointer.changed_button(), pointer.is_horizontal_wheel());
11022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
11032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DCHECK(pointer.IsTouch());
11042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ui_channel_->Send(new MetroViewerHostMsg_TouchDown(pointer.x(),
11052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                       pointer.y(),
1106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                                       pointer.timestamp(),
1107c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                                       pointer.pointer_id()));
11082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
11095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return S_OK;
11105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)HRESULT ChromeAppViewAsh::OnPointerReleased(
11132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    winui::Core::ICoreWindow* sender,
11145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    winui::Core::IPointerEventArgs* args) {
11151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!ui_channel_)
11161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return S_OK;
11171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1118cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  PointerInfoHandler pointer(metro_dpi_scale_, win32_dpi_scale_);
11195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HRESULT hr = pointer.Init(args);
11205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (FAILED(hr))
11215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return hr;
11222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (pointer.IsMouse()) {
11242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    mouse_down_flags_ = ui::EF_NONE;
11255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    SendMouseButton(pointer.x(), pointer.y(), 0, ui::ET_MOUSE_RELEASED,
11265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                    static_cast<uint32>(pointer.changed_button()) |
11275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                    GetKeyboardEventFlags(),
11285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                    pointer.changed_button(),
11295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                    pointer.is_horizontal_wheel());
11302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
11312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DCHECK(pointer.IsTouch());
11322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ui_channel_->Send(new MetroViewerHostMsg_TouchUp(pointer.x(),
11332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                     pointer.y(),
1134c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                                     pointer.timestamp(),
1135c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                                     pointer.pointer_id()));
11362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
11375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return S_OK;
11385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)HRESULT ChromeAppViewAsh::OnWheel(
11412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    winui::Core::ICoreWindow* sender,
11425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    winui::Core::IPointerEventArgs* args) {
11431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!ui_channel_)
11441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return S_OK;
11451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1146cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  PointerInfoHandler pointer(metro_dpi_scale_, win32_dpi_scale_);
11475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HRESULT hr = pointer.Init(args);
11485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (FAILED(hr))
11495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return hr;
11505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(pointer.IsMouse());
11515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SendMouseButton(pointer.x(), pointer.y(), pointer.wheel_delta(),
11521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                  ui::ET_MOUSEWHEEL, GetKeyboardEventFlags(), ui::EF_NONE,
11535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                  pointer.is_horizontal_wheel());
11545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return S_OK;
11555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)HRESULT ChromeAppViewAsh::OnKeyDown(
11582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    winui::Core::ICoreWindow* sender,
11592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    winui::Core::IKeyEventArgs* args) {
11601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!ui_channel_)
11611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return S_OK;
11621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
11635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  winsys::VirtualKey virtual_key;
11645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HRESULT hr = args->get_VirtualKey(&virtual_key);
11655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (FAILED(hr))
11665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return hr;
11675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  winui::Core::CorePhysicalKeyStatus status;
11685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  hr = args->get_KeyStatus(&status);
11695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (FAILED(hr))
11705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return hr;
11715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui_channel_->Send(new MetroViewerHostMsg_KeyDown(virtual_key,
11735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                   status.RepeatCount,
11745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                   status.ScanCode,
11755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                   GetKeyboardEventFlags()));
11765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return S_OK;
11775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)HRESULT ChromeAppViewAsh::OnKeyUp(
11802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    winui::Core::ICoreWindow* sender,
11812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    winui::Core::IKeyEventArgs* args) {
11821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!ui_channel_)
11831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return S_OK;
11841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
11855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  winsys::VirtualKey virtual_key;
11865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HRESULT hr = args->get_VirtualKey(&virtual_key);
11875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (FAILED(hr))
11885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return hr;
11895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  winui::Core::CorePhysicalKeyStatus status;
11905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  hr = args->get_KeyStatus(&status);
11915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (FAILED(hr))
11925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return hr;
11935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui_channel_->Send(new MetroViewerHostMsg_KeyUp(virtual_key,
11955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                 status.RepeatCount,
11965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                 status.ScanCode,
11975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                 GetKeyboardEventFlags()));
11985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return S_OK;
11995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)HRESULT ChromeAppViewAsh::OnAcceleratorKeyDown(
12022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    winui::Core::ICoreDispatcher* sender,
12032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    winui::Core::IAcceleratorKeyEventArgs* args) {
12041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!ui_channel_)
12051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return S_OK;
12061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
12072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  winsys::VirtualKey virtual_key;
12082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  HRESULT hr = args->get_VirtualKey(&virtual_key);
12092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (FAILED(hr))
12102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return hr;
12112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  winui::Core::CorePhysicalKeyStatus status;
12122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  hr = args->get_KeyStatus(&status);
12132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (FAILED(hr))
12142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return hr;
12152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  winui::Core::CoreAcceleratorKeyEventType event_type;
12172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  hr = args->get_EventType(&event_type);
12182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (FAILED(hr))
12192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return hr;
12202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  uint32 keyboard_flags = GetKeyboardEventFlags();
12222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  switch (event_type) {
12242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case winui::Core::CoreAcceleratorKeyEventType_SystemCharacter:
12252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ui_channel_->Send(new MetroViewerHostMsg_Character(virtual_key,
12262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                         status.RepeatCount,
12272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                         status.ScanCode,
12282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                         keyboard_flags));
12292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
12302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case winui::Core::CoreAcceleratorKeyEventType_SystemKeyDown:
1232a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      // Don't send the Alt + F4 combination to Chrome as this is intended to
1233a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      // shut the metro environment down. Reason we check for Control here is
1234a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      // Windows does not shutdown metro if Ctrl is pressed along with Alt F4.
1235a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      // Other key combinations with Alt F4 shutdown metro.
1236a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      if ((virtual_key == VK_F4) && ((keyboard_flags & ui::EF_ALT_DOWN) &&
1237a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          !(keyboard_flags & ui::EF_CONTROL_DOWN)))
1238a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        return S_OK;
12392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ui_channel_->Send(new MetroViewerHostMsg_KeyDown(virtual_key,
12402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                       status.RepeatCount,
12412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                       status.ScanCode,
12422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                       keyboard_flags));
12432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
12442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case winui::Core::CoreAcceleratorKeyEventType_SystemKeyUp:
12462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ui_channel_->Send(new MetroViewerHostMsg_KeyUp(virtual_key,
12472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                     status.RepeatCount,
12482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                     status.ScanCode,
12492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                     keyboard_flags));
12502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
12512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    default:
12532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
12542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
12552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return S_OK;
12562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
12572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HRESULT ChromeAppViewAsh::OnCharacterReceived(
12595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  winui::Core::ICoreWindow* sender,
12605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  winui::Core::ICharacterReceivedEventArgs* args) {
12611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!ui_channel_)
12621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return S_OK;
12631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
12645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unsigned int char_code = 0;
12655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HRESULT hr = args->get_KeyCode(&char_code);
12665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (FAILED(hr))
12675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return hr;
12685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  winui::Core::CorePhysicalKeyStatus status;
12705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  hr = args->get_KeyStatus(&status);
12715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (FAILED(hr))
12725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return hr;
12735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui_channel_->Send(new MetroViewerHostMsg_Character(char_code,
12755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                     status.RepeatCount,
12765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                     status.ScanCode,
12775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                     GetKeyboardEventFlags()));
12785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return S_OK;
12795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1281c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)HRESULT ChromeAppViewAsh::OnWindowActivated(
1282c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    winui::Core::ICoreWindow* sender,
1283c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    winui::Core::IWindowActivatedEventArgs* args) {
12841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!ui_channel_)
12851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return S_OK;
12861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
12871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (args) {
12881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    winui::Core::CoreWindowActivationState state;
12891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    HRESULT hr = args->get_WindowActivationState(&state);
12901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    if (FAILED(hr))
12911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      return hr;
12928bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
12931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // Treat both full activation (Ash was reopened from the Start Screen or
12941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // from any other Metro entry point in Windows) and pointer activation
12951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // (user clicked back in Ash after using another app on another monitor)
12961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // the same.
12971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    if (state == winui::Core::CoreWindowActivationState_CodeActivated ||
12981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        state == winui::Core::CoreWindowActivationState_PointerActivated) {
12991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      if (text_service_)
13001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        text_service_->OnWindowActivated();
13011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      ui_channel_->Send(new MetroViewerHostMsg_WindowActivated(false));
13021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    }
13031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  } else {
13041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // On Windows 7, we force a repaint when the window is activated.
13051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    ui_channel_->Send(new MetroViewerHostMsg_WindowActivated(true));
13068bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
1307c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return S_OK;
1308c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1309c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1310868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)HRESULT ChromeAppViewAsh::HandleSearchRequest(
1311868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    winapp::Activation::IActivatedEventArgs* args) {
1312868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  mswr::ComPtr<winapp::Activation::ISearchActivatedEventArgs> search_args;
1313868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  CheckHR(args->QueryInterface(
1314868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          winapp::Activation::IID_ISearchActivatedEventArgs, &search_args));
1315868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1316868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!ui_channel_) {
1317868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    DVLOG(1) << "Launched to handle search request";
1318f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    LaunchChromeBrowserProcess(L"--windows8-search", args);
1319868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
1320868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1321868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  mswrw::HString search_string;
1322868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  CheckHR(search_args->get_QueryText(search_string.GetAddressOf()));
13235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::string16 search_text(MakeStdWString(search_string.Get()));
1324868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1325868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ui_loop_.PostTask(FROM_HERE,
1326868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                    base::Bind(&ChromeAppViewAsh::OnSearchRequest,
1327868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                    base::Unretained(this),
1328868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                    search_text));
1329868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return S_OK;
1330868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
1331868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1332868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)HRESULT ChromeAppViewAsh::HandleProtocolRequest(
1333868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    winapp::Activation::IActivatedEventArgs* args) {
1334868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DVLOG(1) << __FUNCTION__;
1335868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!ui_channel_)
1336868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    DVLOG(1) << "Launched to handle url request";
1337868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1338868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  mswr::ComPtr<winapp::Activation::IProtocolActivatedEventArgs>
1339868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      protocol_args;
1340868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  CheckHR(args->QueryInterface(
1341868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          winapp::Activation::IID_IProtocolActivatedEventArgs,
1342868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          &protocol_args));
1343868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1344868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  mswr::ComPtr<winfoundtn::IUriRuntimeClass> uri;
1345868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  protocol_args->get_Uri(&uri);
1346868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  mswrw::HString url;
1347868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  uri->get_AbsoluteUri(url.GetAddressOf());
13485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::string16 actual_url(MakeStdWString(url.Get()));
1349868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DVLOG(1) << "Received url request: " << actual_url;
1350868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1351868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ui_loop_.PostTask(FROM_HERE,
1352868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                    base::Bind(&ChromeAppViewAsh::OnNavigateToUrl,
1353868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                               base::Unretained(this),
1354868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                               actual_url));
1355868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return S_OK;
1356868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
1357868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1358f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)HRESULT ChromeAppViewAsh::OnEdgeGestureCompleted(
1359f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    winui::Input::IEdgeGesture* gesture,
1360f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    winui::Input::IEdgeGestureEventArgs* args) {
13611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (ui_channel_)
13621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    ui_channel_->Send(new MetroViewerHostMsg_EdgeGesture());
1363f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return S_OK;
1364f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
1365f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
13665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ChromeAppViewAsh::OnSearchRequest(const base::string16& search_string) {
13671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (ui_channel_)
13681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    ui_channel_->Send(new MetroViewerHostMsg_SearchRequest(search_string));
1369868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
1370868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
13715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ChromeAppViewAsh::OnNavigateToUrl(const base::string16& url) {
13721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (ui_channel_)
13731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    ui_channel_->Send(new MetroViewerHostMsg_OpenURL(url));
1374868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
1375868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
13767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)HRESULT ChromeAppViewAsh::OnSizeChanged(winui::Core::ICoreWindow* sender,
13777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    winui::Core::IWindowSizeChangedEventArgs* args) {
13787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (!window_) {
13797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return S_OK;
13807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
13817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
13820529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // winui::Core::IWindowSizeChangedEventArgs args->Size appears to return
13830529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // scaled values under HiDPI. We will instead use GetWindowRect() which
13840529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // should always return values in Pixels.
13850529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  RECT rect = {0};
13860529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  ::GetWindowRect(core_window_hwnd_, &rect);
13877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
13880529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  uint32 cx = static_cast<uint32>(rect.right - rect.left);
13890529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  uint32 cy = static_cast<uint32>(rect.bottom - rect.top);
13907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
13917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  DVLOG(1) << "Window size changed: width=" << cx << ", height=" << cy;
13927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ui_channel_->Send(new MetroViewerHostMsg_WindowSizeChanged(cx, cy));
13937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return S_OK;
13947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
13955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid ChromeAppViewAsh::StartChromeOSMode() {
13971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  static int ms_elapsed = 0;
13981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
13991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!IPC::Channel::IsNamedServerInitialized(
14001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          win8::kMetroViewerIPCChannelName) && ms_elapsed < 10000) {
14011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    ms_elapsed += 100;
14021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    ui_loop_.PostDelayedTask(FROM_HERE,
14031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        base::Bind(base::IgnoreResult(&ChromeAppViewAsh::StartChromeOSMode),
14041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                   base::Unretained(this)),
14051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        base::TimeDelta::FromMilliseconds(kChromeChannelPollTimerMs));
14061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return;
14071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
14081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
14091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!IPC::Channel::IsNamedServerInitialized(
14101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          win8::kMetroViewerIPCChannelName)) {
14111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    DVLOG(1) << "Failed to connect to chrome channel : "
14121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci             << win8::kMetroViewerIPCChannelName;
14131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    DVLOG(1) << "Exiting. Elapsed time :" << ms_elapsed;
14141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    PostMessage(core_window_hwnd_, WM_CLOSE, 0, 0);
14151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return;
14161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
14171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
14181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DVLOG(1) << "Found channel : " << win8::kMetroViewerIPCChannelName;
14191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
14201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK(channel_listener_);
14211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
14221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // In Aura mode we create an IPC channel to the browser, then ask it to
14231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // connect to us.
14241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ui_channel_ =
14251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      IPC::ChannelProxy::Create(win8::kMetroViewerIPCChannelName,
14261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                IPC::Channel::MODE_NAMED_CLIENT,
14271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                channel_listener_,
14281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                io_thread_->message_loop_proxy());
14291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DVLOG(1) << "Created channel proxy";
14301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
14311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Upon receipt of the MetroViewerHostMsg_SetTargetSurface message the
14321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // browser will use D3D from the browser process to present to our Window.
14331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ui_channel_->Send(new MetroViewerHostMsg_SetTargetSurface(
14341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      gfx::NativeViewId(core_window_hwnd_),
14351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      win32_dpi_scale_));
14361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DVLOG(1) << "ICoreWindow sent " << core_window_hwnd_;
14371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
14381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Send an initial size message so that the Ash root window host gets sized
14391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // correctly.
14401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  RECT rect = {0};
14411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ::GetWindowRect(core_window_hwnd_, &rect);
14421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ui_channel_->Send(
14431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      new MetroViewerHostMsg_WindowSizeChanged(rect.right - rect.left,
14441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                               rect.bottom - rect.top));
14451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
14461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  input_source_ = metro_driver::InputSource::Create();
14471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (input_source_) {
14481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    input_source_->AddObserver(this);
14491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // Send an initial input source.
14501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    OnInputSourceChanged();
14511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
14521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
14531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Start receiving IME popup window notifications.
14541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  metro_driver::AddImePopupObserver(this);
14551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
14561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DVLOG(1) << "Channel setup complete";
14571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
14581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
14595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)///////////////////////////////////////////////////////////////////////////////
14605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ChromeAppViewFactory::ChromeAppViewFactory(
1462a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    winapp::Core::ICoreApplication* icore_app) {
14635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mswr::ComPtr<winapp::Core::ICoreApplication> core_app(icore_app);
14645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mswr::ComPtr<winapp::Core::ICoreApplicationExit> app_exit;
14655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CheckHR(core_app.As(&app_exit));
14665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  globals.app_exit = app_exit.Detach();
14675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
14685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IFACEMETHODIMP
14705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ChromeAppViewFactory::CreateView(winapp::Core::IFrameworkView** view) {
14715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *view = mswr::Make<ChromeAppViewAsh>().Detach();
14725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return (*view) ? S_OK :  E_OUTOFMEMORY;
14735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1474