1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef WIN8_METRO_DRIVER_CHROME_APP_VIEW_ASH_H_ 6 #define WIN8_METRO_DRIVER_CHROME_APP_VIEW_ASH_H_ 7 8 #include <windows.applicationmodel.core.h> 9 #include <windows.ui.core.h> 10 #include <windows.ui.input.h> 11 #include <windows.ui.viewmanagement.h> 12 13 #include "base/memory/scoped_ptr.h" 14 #include "base/message_loop/message_loop.h" 15 #include "base/strings/string16.h" 16 #include "base/threading/thread.h" 17 #include "ipc/ipc_listener.h" 18 #include "ui/events/event_constants.h" 19 #include "win8/metro_driver/direct3d_helper.h" 20 #include "win8/metro_driver/ime/ime_popup_observer.h" 21 #include "win8/metro_driver/ime/input_source_observer.h" 22 #include "win8/metro_driver/ime/text_service_delegate.h" 23 24 namespace base { 25 class FilePath; 26 } 27 28 namespace IPC { 29 class Listener; 30 class ChannelProxy; 31 } 32 33 namespace metro_driver { 34 class InputSource; 35 class TextService; 36 } 37 38 namespace metro_viewer { 39 struct CharacterBounds; 40 struct UnderlineInfo; 41 } 42 43 class OpenFilePickerSession; 44 class SaveFilePickerSession; 45 class FolderPickerSession; 46 class FilePickerSessionBase; 47 48 struct MetroViewerHostMsg_SaveAsDialogParams; 49 50 enum MetroTerminateMethod { 51 TERMINATE_USING_KEY_SEQUENCE = 1, 52 TERMINATE_USING_PROCESS_EXIT = 2, 53 }; 54 55 class ChromeAppViewAsh 56 : public mswr::RuntimeClass<winapp::Core::IFrameworkView>, 57 public metro_driver::ImePopupObserver, 58 public metro_driver::InputSourceObserver, 59 public metro_driver::TextServiceDelegate { 60 public: 61 ChromeAppViewAsh(); 62 ~ChromeAppViewAsh(); 63 64 // IViewProvider overrides. 65 IFACEMETHOD(Initialize)(winapp::Core::ICoreApplicationView* view); 66 IFACEMETHOD(SetWindow)(winui::Core::ICoreWindow* window); 67 IFACEMETHOD(Load)(HSTRING entryPoint); 68 IFACEMETHOD(Run)(); 69 IFACEMETHOD(Uninitialize)(); 70 71 // Helper function to unsnap the chrome metro app if it is snapped. 72 // Returns S_OK on success. 73 static HRESULT Unsnap(); 74 75 void OnActivateDesktop(const base::FilePath& file_path, bool ash_exit); 76 void OnOpenURLOnDesktop(const base::FilePath& shortcut, 77 const base::string16& url); 78 void OnSetCursor(HCURSOR cursor); 79 void OnDisplayFileOpenDialog(const base::string16& title, 80 const base::string16& filter, 81 const base::FilePath& default_path, 82 bool allow_multiple_files); 83 void OnDisplayFileSaveAsDialog( 84 const MetroViewerHostMsg_SaveAsDialogParams& params); 85 void OnDisplayFolderPicker(const base::string16& title); 86 void OnSetCursorPos(int x, int y); 87 88 // This function is invoked when the open file operation completes. The 89 // result of the operation is passed in along with the OpenFilePickerSession 90 // instance which is deleted after we read the required information from 91 // the OpenFilePickerSession class. 92 void OnOpenFileCompleted(OpenFilePickerSession* open_file_picker, 93 bool success); 94 95 // This function is invoked when the save file operation completes. The 96 // result of the operation is passed in along with the SaveFilePickerSession 97 // instance which is deleted after we read the required information from 98 // the SaveFilePickerSession class. 99 void OnSaveFileCompleted(SaveFilePickerSession* save_file_picker, 100 bool success); 101 102 // This function is invoked when the folder picker operation completes. The 103 // result of the operation is passed in along with the FolderPickerSession 104 // instance which is deleted after we read the required information from 105 // the FolderPickerSession class. 106 void OnFolderPickerCompleted(FolderPickerSession* folder_picker, 107 bool success); 108 109 void OnImeCancelComposition(); 110 void OnImeUpdateTextInputClient( 111 const std::vector<int32>& input_scopes, 112 const std::vector<metro_viewer::CharacterBounds>& character_bounds); 113 114 void OnMetroExit(MetroTerminateMethod method); 115 116 HWND core_window_hwnd() const { return core_window_hwnd_; } 117 118 119 private: 120 class PointerInfoHandler; 121 122 // ImePopupObserver overrides. 123 virtual void OnImePopupChanged(ImePopupObserver::EventType event) OVERRIDE; 124 125 // InputSourceObserver overrides. 126 virtual void OnInputSourceChanged() OVERRIDE; 127 128 // TextServiceDelegate overrides. 129 virtual void OnCompositionChanged( 130 const base::string16& text, 131 int32 selection_start, 132 int32 selection_end, 133 const std::vector<metro_viewer::UnderlineInfo>& underlines) OVERRIDE; 134 virtual void OnTextCommitted(const base::string16& text) OVERRIDE; 135 136 // Convenience for sending a MetroViewerHostMsg_MouseButton with the specified 137 // parameters. 138 void SendMouseButton(int x, 139 int y, 140 int extra, 141 ui::EventType event_type, 142 uint32 flags, 143 ui::EventFlags changed_button, 144 bool is_horizontal_wheel); 145 146 // Win8 only generates a mouse press for the initial button that goes down and 147 // a release when the last button is released. Any intermediary presses (or 148 // releases) do not result in a new press/release event. Instead a move is 149 // generated with the winui::Input::PointerUpdateKind identifying what 150 // changed. This function generates the necessary intermediary events (as 151 // necessary). 152 void GenerateMouseEventFromMoveIfNecessary(const PointerInfoHandler& pointer); 153 154 HRESULT OnActivate(winapp::Core::ICoreApplicationView* view, 155 winapp::Activation::IActivatedEventArgs* args); 156 157 HRESULT OnPointerMoved(winui::Core::ICoreWindow* sender, 158 winui::Core::IPointerEventArgs* args); 159 160 HRESULT OnPointerPressed(winui::Core::ICoreWindow* sender, 161 winui::Core::IPointerEventArgs* args); 162 163 HRESULT OnPointerReleased(winui::Core::ICoreWindow* sender, 164 winui::Core::IPointerEventArgs* args); 165 166 HRESULT OnWheel(winui::Core::ICoreWindow* sender, 167 winui::Core::IPointerEventArgs* args); 168 169 HRESULT OnKeyDown(winui::Core::ICoreWindow* sender, 170 winui::Core::IKeyEventArgs* args); 171 172 HRESULT OnKeyUp(winui::Core::ICoreWindow* sender, 173 winui::Core::IKeyEventArgs* args); 174 175 // Invoked for system keys like Alt, etc. 176 HRESULT OnAcceleratorKeyDown(winui::Core::ICoreDispatcher* sender, 177 winui::Core::IAcceleratorKeyEventArgs* args); 178 179 HRESULT OnCharacterReceived(winui::Core::ICoreWindow* sender, 180 winui::Core::ICharacterReceivedEventArgs* args); 181 182 HRESULT OnWindowActivated(winui::Core::ICoreWindow* sender, 183 winui::Core::IWindowActivatedEventArgs* args); 184 185 // Helper to handle search requests received via the search charm in ASH. 186 HRESULT HandleSearchRequest(winapp::Activation::IActivatedEventArgs* args); 187 // Helper to handle http/https url requests in ASH. 188 HRESULT HandleProtocolRequest(winapp::Activation::IActivatedEventArgs* args); 189 190 HRESULT OnEdgeGestureCompleted(winui::Input::IEdgeGesture* gesture, 191 winui::Input::IEdgeGestureEventArgs* args); 192 193 // Tasks posted to the UI thread to initiate the search/url navigation 194 // requests. 195 void OnSearchRequest(const base::string16& search_string); 196 void OnNavigateToUrl(const base::string16& url); 197 198 HRESULT OnSizeChanged(winui::Core::ICoreWindow* sender, 199 winui::Core::IWindowSizeChangedEventArgs* args); 200 201 // This function checks if the Chrome browser channel is initialized. If yes 202 // then it goes ahead and starts up the viewer in Chrome OS mode. If not it 203 // posts a delayed task and checks again. It does this for a duration of 10 204 // seconds and then bails. 205 void StartChromeOSMode(); 206 207 mswr::ComPtr<winui::Core::ICoreWindow> window_; 208 mswr::ComPtr<winapp::Core::ICoreApplicationView> view_; 209 EventRegistrationToken activated_token_; 210 EventRegistrationToken pointermoved_token_; 211 EventRegistrationToken pointerpressed_token_; 212 EventRegistrationToken pointerreleased_token_; 213 EventRegistrationToken wheel_token_; 214 EventRegistrationToken keydown_token_; 215 EventRegistrationToken keyup_token_; 216 EventRegistrationToken character_received_token_; 217 EventRegistrationToken accel_keydown_token_; 218 EventRegistrationToken accel_keyup_token_; 219 EventRegistrationToken window_activated_token_; 220 EventRegistrationToken sizechange_token_; 221 EventRegistrationToken edgeevent_token_; 222 223 // Keep state about which button is currently down, if any, as PointerMoved 224 // events do not contain that state, but Ash's MouseEvents need it. Value is 225 // as a bitmask of ui::EventFlags. 226 uint32 mouse_down_flags_; 227 228 // Set the D3D swap chain and nothing else. 229 metro_driver::Direct3DHelper direct3d_helper_; 230 231 // The IPC channel IO thread. 232 scoped_ptr<base::Thread> io_thread_; 233 234 // The channel to Chrome, in particular to the MetroViewerProcessHost. 235 scoped_ptr<IPC::ChannelProxy> ui_channel_; 236 237 // The actual window behind the view surface. 238 HWND core_window_hwnd_; 239 240 // UI message loop to allow message passing into this thread. 241 base::MessageLoopForUI ui_loop_; 242 243 // For IME support. 244 scoped_ptr<metro_driver::InputSource> input_source_; 245 scoped_ptr<metro_driver::TextService> text_service_; 246 247 // The metro device scale factor as reported by the winrt interfaces. 248 float metro_dpi_scale_; 249 // The win32 dpi scale which is queried via GetDeviceCaps. Please refer to 250 // ui/gfx/win/dpi.cc for more information. 251 float win32_dpi_scale_; 252 253 // The cursor set by the chroem browser process. 254 HCURSOR last_cursor_; 255 256 // Pointer to the channel listener for the channel between the viewer and 257 // the browser. 258 IPC::Listener* channel_listener_; 259 }; 260 261 #endif // WIN8_METRO_DRIVER_CHROME_APP_VIEW_ASH_H_ 262