Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "win8/metro_driver/stdafx.h" | 5 #include "win8/metro_driver/stdafx.h" |
| 6 #include "win8/metro_driver/chrome_app_view_ash.h" | 6 #include "win8/metro_driver/chrome_app_view_ash.h" |
| 7 | 7 |
| 8 #include <corewindow.h> | 8 #include <corewindow.h> |
| 9 #include <shellapi.h> | 9 #include <shellapi.h> |
| 10 #include <windows.foundation.h> | 10 #include <windows.foundation.h> |
| 11 | 11 |
| 12 #include "base/bind.h" | 12 #include "base/bind.h" |
| 13 #include "base/command_line.h" | 13 #include "base/command_line.h" |
| 14 #include "base/files/file_path.h" | 14 #include "base/files/file_path.h" |
| 15 #include "base/message_loop/message_loop.h" | 15 #include "base/message_loop/message_loop.h" |
| 16 #include "base/path_service.h" | 16 #include "base/path_service.h" |
| 17 #include "base/threading/thread.h" | |
| 18 #include "base/win/metro.h" | 17 #include "base/win/metro.h" |
| 19 #include "base/win/win_util.h" | 18 #include "base/win/win_util.h" |
| 20 #include "base/win/windows_version.h" | 19 #include "base/win/windows_version.h" |
| 21 #include "chrome/common/chrome_switches.h" | 20 #include "chrome/common/chrome_switches.h" |
| 22 #include "ipc/ipc_channel.h" | 21 #include "ipc/ipc_channel.h" |
| 23 #include "ipc/ipc_channel_proxy.h" | 22 #include "ipc/ipc_channel_proxy.h" |
| 24 #include "ipc/ipc_sender.h" | 23 #include "ipc/ipc_sender.h" |
| 25 #include "ui/events/gesture_detection/motion_event.h" | 24 #include "ui/events/gesture_detection/motion_event.h" |
| 26 #include "ui/gfx/geometry/point_conversions.h" | 25 #include "ui/gfx/geometry/point_conversions.h" |
| 27 #include "ui/gfx/win/dpi.h" | 26 #include "ui/gfx/win/dpi.h" |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 80 | 79 |
| 81 namespace { | 80 namespace { |
| 82 | 81 |
| 83 enum KeyModifier { | 82 enum KeyModifier { |
| 84 NONE, | 83 NONE, |
| 85 SHIFT = 1, | 84 SHIFT = 1, |
| 86 CONTROL = 2, | 85 CONTROL = 2, |
| 87 ALT = 4 | 86 ALT = 4 |
| 88 }; | 87 }; |
| 89 | 88 |
| 89 const int kChromeChannelPollTimerMs = 100; | |
| 90 const UINT_PTR kChromeChannelPollTimerId = 0xdeadbabe; | |
| 91 | |
| 90 // Helper function to send keystrokes via the SendInput function. | 92 // Helper function to send keystrokes via the SendInput function. |
| 91 // mnemonic_char: The keystroke to be sent. | 93 // mnemonic_char: The keystroke to be sent. |
| 92 // modifiers: Combination with Alt, Ctrl, Shift, etc. | 94 // modifiers: Combination with Alt, Ctrl, Shift, etc. |
| 93 void SendKeySequence( | 95 void SendKeySequence( |
| 94 WORD mnemonic_char, KeyModifier modifiers) { | 96 WORD mnemonic_char, KeyModifier modifiers) { |
| 95 INPUT keys[4] = {0}; // Keyboard events | 97 INPUT keys[4] = {0}; // Keyboard events |
| 96 int key_count = 0; // Number of generated events | 98 int key_count = 0; // Number of generated events |
| 97 | 99 |
| 98 if (modifiers & SHIFT) { | 100 if (modifiers & SHIFT) { |
| 99 keys[key_count].type = INPUT_KEYBOARD; | 101 keys[key_count].type = INPUT_KEYBOARD; |
| (...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 266 base::Bind(&ChromeAppViewAsh::OnImeUpdateTextInputClient, | 268 base::Bind(&ChromeAppViewAsh::OnImeUpdateTextInputClient, |
| 267 base::Unretained(app_view_), | 269 base::Unretained(app_view_), |
| 268 input_scopes, | 270 input_scopes, |
| 269 character_bounds)); | 271 character_bounds)); |
| 270 } | 272 } |
| 271 | 273 |
| 272 scoped_refptr<base::MessageLoopProxy> ui_proxy_; | 274 scoped_refptr<base::MessageLoopProxy> ui_proxy_; |
| 273 ChromeAppViewAsh* app_view_; | 275 ChromeAppViewAsh* app_view_; |
| 274 }; | 276 }; |
| 275 | 277 |
| 276 bool WaitForChromeIPCConnection(const std::string& channel_name) { | |
| 277 int ms_elapsed = 0; | |
| 278 while (!IPC::Channel::IsNamedServerInitialized(channel_name) && | |
| 279 ms_elapsed < 10000) { | |
| 280 ms_elapsed += 100; | |
| 281 Sleep(100); | |
| 282 } | |
| 283 return IPC::Channel::IsNamedServerInitialized(channel_name); | |
| 284 } | |
| 285 | |
| 286 void RunMessageLoop(winui::Core::ICoreDispatcher* dispatcher) { | 278 void RunMessageLoop(winui::Core::ICoreDispatcher* dispatcher) { |
| 287 // We're entering a nested message loop, let's allow dispatching | 279 // We're entering a nested message loop, let's allow dispatching |
| 288 // tasks while we're in there. | 280 // tasks while we're in there. |
| 289 base::MessageLoop::current()->SetNestableTasksAllowed(true); | 281 base::MessageLoop::current()->SetNestableTasksAllowed(true); |
| 290 | 282 |
| 291 // Enter main core message loop. There are several ways to exit it | 283 // Enter main core message loop. There are several ways to exit it |
| 292 // Nicely: | 284 // Nicely: |
| 293 // 1 - User action like ALT-F4. | 285 // 1 - User action like ALT-F4. |
| 294 // 2 - Calling ICoreApplicationExit::Exit(). | 286 // 2 - Calling ICoreApplicationExit::Exit(). |
| 295 // 3- Posting WM_CLOSE to the core window. | 287 // 3- Posting WM_CLOSE to the core window. |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 352 | 344 |
| 353 SHELLEXECUTEINFO sei = { sizeof(sei) }; | 345 SHELLEXECUTEINFO sei = { sizeof(sei) }; |
| 354 sei.nShow = SW_SHOWNORMAL; | 346 sei.nShow = SW_SHOWNORMAL; |
| 355 sei.lpFile = chrome_exe_path.value().c_str(); | 347 sei.lpFile = chrome_exe_path.value().c_str(); |
| 356 sei.lpDirectory = L""; | 348 sei.lpDirectory = L""; |
| 357 sei.lpParameters = parameters.c_str(); | 349 sei.lpParameters = parameters.c_str(); |
| 358 ::ShellExecuteEx(&sei); | 350 ::ShellExecuteEx(&sei); |
| 359 return true; | 351 return true; |
| 360 } | 352 } |
| 361 | 353 |
| 354 ChromeChannelListener* g_ui_channel_listener = NULL; | |
|
scottmg
2014/09/24 19:33:35
could this be a member of ChromeAppViewAsh too so
ananta
2014/09/24 19:57:18
Done.
| |
| 355 | |
| 362 } // namespace | 356 } // namespace |
| 363 | 357 |
| 364 // This class helps decoding the pointer properties of an event. | 358 // This class helps decoding the pointer properties of an event. |
| 365 class ChromeAppViewAsh::PointerInfoHandler { | 359 class ChromeAppViewAsh::PointerInfoHandler { |
| 366 public: | 360 public: |
| 367 PointerInfoHandler(float metro_dpi_scale, float win32_dpi_scale) | 361 PointerInfoHandler(float metro_dpi_scale, float win32_dpi_scale) |
| 368 : x_(0), | 362 : x_(0), |
| 369 y_(0), | 363 y_(0), |
| 370 wheel_delta_(0), | 364 wheel_delta_(0), |
| 371 update_kind_(winui::Input::PointerUpdateKind_Other), | 365 update_kind_(winui::Input::PointerUpdateKind_Other), |
| (...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 518 | 512 |
| 519 // The metro device scale factor as reported by the winrt interfaces. | 513 // The metro device scale factor as reported by the winrt interfaces. |
| 520 float metro_dpi_scale_; | 514 float metro_dpi_scale_; |
| 521 // The win32 dpi scale which is queried via GetDeviceCaps. Please refer to | 515 // The win32 dpi scale which is queried via GetDeviceCaps. Please refer to |
| 522 // ui/gfx/win/dpi.cc for more information. | 516 // ui/gfx/win/dpi.cc for more information. |
| 523 float win32_dpi_scale_; | 517 float win32_dpi_scale_; |
| 524 | 518 |
| 525 DISALLOW_COPY_AND_ASSIGN(PointerInfoHandler); | 519 DISALLOW_COPY_AND_ASSIGN(PointerInfoHandler); |
| 526 }; | 520 }; |
| 527 | 521 |
| 522 ChromeAppViewAsh* ChromeAppViewAsh::g_instance_ = NULL; | |
| 523 | |
| 528 ChromeAppViewAsh::ChromeAppViewAsh() | 524 ChromeAppViewAsh::ChromeAppViewAsh() |
| 529 : mouse_down_flags_(ui::EF_NONE), | 525 : mouse_down_flags_(ui::EF_NONE), |
| 530 ui_channel_(nullptr), | 526 ui_channel_(nullptr), |
| 531 core_window_hwnd_(NULL), | 527 core_window_hwnd_(NULL), |
| 532 metro_dpi_scale_(0), | 528 metro_dpi_scale_(0), |
| 533 win32_dpi_scale_(0), | 529 win32_dpi_scale_(0), |
| 534 last_cursor_(NULL) { | 530 last_cursor_(NULL) { |
| 535 DVLOG(1) << __FUNCTION__; | 531 DVLOG(1) << __FUNCTION__; |
| 536 globals.previous_state = | 532 globals.previous_state = |
| 537 winapp::Activation::ApplicationExecutionState_NotRunning; | 533 winapp::Activation::ApplicationExecutionState_NotRunning; |
| 534 DCHECK(!g_instance_); | |
| 535 | |
| 536 g_instance_ = this; | |
| 538 } | 537 } |
| 539 | 538 |
| 540 ChromeAppViewAsh::~ChromeAppViewAsh() { | 539 ChromeAppViewAsh::~ChromeAppViewAsh() { |
| 541 DVLOG(1) << __FUNCTION__; | 540 DVLOG(1) << __FUNCTION__; |
| 542 } | 541 } |
| 543 | 542 |
| 544 IFACEMETHODIMP | 543 IFACEMETHODIMP |
| 545 ChromeAppViewAsh::Initialize(winapp::Core::ICoreApplicationView* view) { | 544 ChromeAppViewAsh::Initialize(winapp::Core::ICoreApplicationView* view) { |
| 546 view_ = view; | 545 view_ = view; |
| 547 DVLOG(1) << __FUNCTION__; | 546 DVLOG(1) << __FUNCTION__; |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 671 } | 670 } |
| 672 | 671 |
| 673 IFACEMETHODIMP | 672 IFACEMETHODIMP |
| 674 ChromeAppViewAsh::Run() { | 673 ChromeAppViewAsh::Run() { |
| 675 DVLOG(1) << __FUNCTION__; | 674 DVLOG(1) << __FUNCTION__; |
| 676 mswr::ComPtr<winui::Core::ICoreDispatcher> dispatcher; | 675 mswr::ComPtr<winui::Core::ICoreDispatcher> dispatcher; |
| 677 HRESULT hr = window_->get_Dispatcher(dispatcher.GetAddressOf()); | 676 HRESULT hr = window_->get_Dispatcher(dispatcher.GetAddressOf()); |
| 678 CheckHR(hr, "Dispatcher failed."); | 677 CheckHR(hr, "Dispatcher failed."); |
| 679 | 678 |
| 680 // Create the IPC channel IO thread. It needs to out-live the ChannelProxy. | 679 // Create the IPC channel IO thread. It needs to out-live the ChannelProxy. |
| 681 base::Thread io_thread("metro_IO_thread"); | 680 io_thread_.reset(new base::Thread("metro_IO_thread")); |
| 682 base::Thread::Options options; | 681 base::Thread::Options options; |
| 683 options.message_loop_type = base::MessageLoop::TYPE_IO; | 682 options.message_loop_type = base::MessageLoop::TYPE_IO; |
| 684 io_thread.StartWithOptions(options); | 683 io_thread_->StartWithOptions(options); |
| 685 | 684 |
| 686 // Start up Chrome and wait for the desired IPC server connection to exist. | 685 ChromeChannelListener ui_channel_listener(&ui_loop_, this); |
| 687 WaitForChromeIPCConnection(win8::kMetroViewerIPCChannelName); | |
| 688 | 686 |
| 689 // In Aura mode we create an IPC channel to the browser, then ask it to | 687 // We can't do anything until the Chrome browser IPC channel is initialized. |
| 690 // connect to us. | 688 // Lazy initialization in a timer. |
| 691 ChromeChannelListener ui_channel_listener(&ui_loop_, this); | 689 g_ui_channel_listener = &ui_channel_listener; |
| 692 scoped_ptr<IPC::ChannelProxy> channel = | |
| 693 IPC::ChannelProxy::Create(win8::kMetroViewerIPCChannelName, | |
| 694 IPC::Channel::MODE_NAMED_CLIENT, | |
| 695 &ui_channel_listener, | |
| 696 io_thread.message_loop_proxy()); | |
| 697 ui_channel_ = channel.get(); | |
| 698 | 690 |
| 699 // Upon receipt of the MetroViewerHostMsg_SetTargetSurface message the | 691 UINT_PTR channel_setup_timer_id = |
| 700 // browser will use D3D from the browser process to present to our Window. | 692 ::SetTimer(core_window_hwnd_, |
| 701 ui_channel_->Send(new MetroViewerHostMsg_SetTargetSurface( | 693 kChromeChannelPollTimerId, |
| 702 gfx::NativeViewId(core_window_hwnd_), win32_dpi_scale_)); | 694 kChromeChannelPollTimerMs, |
| 703 DVLOG(1) << "ICoreWindow sent " << core_window_hwnd_; | 695 &ChromeAppViewAsh::StartChromeOSMode); |
| 704 | 696 |
| 705 // Send an initial size message so that the Ash root window host gets sized | 697 // Post the task that'll do the inner Metro message pumping to it. |
| 706 // correctly. | |
| 707 RECT rect = {0}; | |
| 708 ::GetWindowRect(core_window_hwnd_, &rect); | |
| 709 ui_channel_->Send( | |
| 710 new MetroViewerHostMsg_WindowSizeChanged(rect.right - rect.left, | |
| 711 rect.bottom - rect.top)); | |
| 712 | |
| 713 input_source_ = metro_driver::InputSource::Create(); | |
| 714 if (input_source_) { | |
| 715 input_source_->AddObserver(this); | |
| 716 // Send an initial input source. | |
| 717 OnInputSourceChanged(); | |
| 718 } | |
| 719 | |
| 720 // Start receiving IME popup window notifications. | |
| 721 metro_driver::AddImePopupObserver(this); | |
| 722 | |
| 723 // And post the task that'll do the inner Metro message pumping to it. | |
| 724 ui_loop_.PostTask(FROM_HERE, base::Bind(&RunMessageLoop, dispatcher.Get())); | 698 ui_loop_.PostTask(FROM_HERE, base::Bind(&RunMessageLoop, dispatcher.Get())); |
| 725 ui_loop_.Run(); | 699 ui_loop_.Run(); |
| 726 | 700 |
| 701 io_thread_.reset(NULL); | |
| 702 ui_channel_.reset(NULL); | |
| 703 | |
| 727 DVLOG(0) << "ProcessEvents done, hr=" << hr; | 704 DVLOG(0) << "ProcessEvents done, hr=" << hr; |
| 728 return hr; | 705 return hr; |
| 729 } | 706 } |
| 730 | 707 |
| 731 IFACEMETHODIMP | 708 IFACEMETHODIMP |
| 732 ChromeAppViewAsh::Uninitialize() { | 709 ChromeAppViewAsh::Uninitialize() { |
| 733 DVLOG(1) << __FUNCTION__; | 710 DVLOG(1) << __FUNCTION__; |
| 734 metro_driver::RemoveImePopupObserver(this); | 711 metro_driver::RemoveImePopupObserver(this); |
| 735 input_source_.reset(); | 712 input_source_.reset(); |
| 736 text_service_.reset(); | 713 text_service_.reset(); |
| (...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 966 ui_channel_->Close(); | 943 ui_channel_->Close(); |
| 967 | 944 |
| 968 HWND core_window = core_window_hwnd(); | 945 HWND core_window = core_window_hwnd(); |
| 969 ::PostMessage(core_window, WM_CLOSE, 0, 0); | 946 ::PostMessage(core_window, WM_CLOSE, 0, 0); |
| 970 | 947 |
| 971 globals.app_exit->Exit(); | 948 globals.app_exit->Exit(); |
| 972 } | 949 } |
| 973 } | 950 } |
| 974 | 951 |
| 975 void ChromeAppViewAsh::OnInputSourceChanged() { | 952 void ChromeAppViewAsh::OnInputSourceChanged() { |
| 976 if (!input_source_) | 953 if (!input_source_) |
|
scottmg
2014/09/24 19:33:35
ui_channel_ guard?
ananta
2014/09/24 19:57:18
Not needed here because this is called after the c
| |
| 977 return; | 954 return; |
| 978 | 955 |
| 979 LANGID langid = 0; | 956 LANGID langid = 0; |
| 980 bool is_ime = false; | 957 bool is_ime = false; |
| 981 if (!input_source_->GetActiveSource(&langid, &is_ime)) { | 958 if (!input_source_->GetActiveSource(&langid, &is_ime)) { |
| 982 LOG(ERROR) << "GetActiveSource failed"; | 959 LOG(ERROR) << "GetActiveSource failed"; |
| 983 return; | 960 return; |
| 984 } | 961 } |
| 985 ui_channel_->Send(new MetroViewerHostMsg_ImeInputSourceChanged(langid, | 962 ui_channel_->Send(new MetroViewerHostMsg_ImeInputSourceChanged(langid, |
| 986 is_ime)); | 963 is_ime)); |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 999 ui_channel_->Send(new MetroViewerHostMsg_ImeTextCommitted(text)); | 976 ui_channel_->Send(new MetroViewerHostMsg_ImeTextCommitted(text)); |
| 1000 } | 977 } |
| 1001 | 978 |
| 1002 void ChromeAppViewAsh::SendMouseButton(int x, | 979 void ChromeAppViewAsh::SendMouseButton(int x, |
| 1003 int y, | 980 int y, |
| 1004 int extra, | 981 int extra, |
| 1005 ui::EventType event_type, | 982 ui::EventType event_type, |
| 1006 uint32 flags, | 983 uint32 flags, |
| 1007 ui::EventFlags changed_button, | 984 ui::EventFlags changed_button, |
| 1008 bool is_horizontal_wheel) { | 985 bool is_horizontal_wheel) { |
| 1009 MetroViewerHostMsg_MouseButtonParams params; | 986 MetroViewerHostMsg_MouseButtonParams params; |
|
scottmg
2014/09/24 19:33:35
ui_channel_ guard?
ananta
2014/09/24 19:57:18
Done.
| |
| 1010 params.x = static_cast<int32>(x); | 987 params.x = static_cast<int32>(x); |
| 1011 params.y = static_cast<int32>(y); | 988 params.y = static_cast<int32>(y); |
| 1012 params.extra = static_cast<int32>(extra); | 989 params.extra = static_cast<int32>(extra); |
| 1013 params.event_type = event_type; | 990 params.event_type = event_type; |
| 1014 params.flags = static_cast<int32>(flags); | 991 params.flags = static_cast<int32>(flags); |
| 1015 params.changed_button = changed_button; | 992 params.changed_button = changed_button; |
| 1016 params.is_horizontal_wheel = is_horizontal_wheel; | 993 params.is_horizontal_wheel = is_horizontal_wheel; |
| 1017 ui_channel_->Send(new MetroViewerHostMsg_MouseButton(params)); | 994 ui_channel_->Send(new MetroViewerHostMsg_MouseButton(params)); |
| 1018 } | 995 } |
| 1019 | 996 |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1068 // in turn launches the chrome browser process in desktop mode via | 1045 // in turn launches the chrome browser process in desktop mode via |
| 1069 // ShellExecute. If we call ICoreWindow::Activate before this, then | 1046 // ShellExecute. If we call ICoreWindow::Activate before this, then |
| 1070 // Windows kills the metro chrome process when it calls ShellExecute. Seems | 1047 // Windows kills the metro chrome process when it calls ShellExecute. Seems |
| 1071 // to be a bug. | 1048 // to be a bug. |
| 1072 window_->Activate(); | 1049 window_->Activate(); |
| 1073 return S_OK; | 1050 return S_OK; |
| 1074 } | 1051 } |
| 1075 | 1052 |
| 1076 HRESULT ChromeAppViewAsh::OnPointerMoved(winui::Core::ICoreWindow* sender, | 1053 HRESULT ChromeAppViewAsh::OnPointerMoved(winui::Core::ICoreWindow* sender, |
| 1077 winui::Core::IPointerEventArgs* args) { | 1054 winui::Core::IPointerEventArgs* args) { |
| 1055 if (!ui_channel_) | |
| 1056 return S_OK; | |
| 1057 | |
| 1078 PointerInfoHandler pointer(metro_dpi_scale_, win32_dpi_scale_); | 1058 PointerInfoHandler pointer(metro_dpi_scale_, win32_dpi_scale_); |
| 1079 HRESULT hr = pointer.Init(args); | 1059 HRESULT hr = pointer.Init(args); |
| 1080 if (FAILED(hr)) | 1060 if (FAILED(hr)) |
| 1081 return hr; | 1061 return hr; |
| 1082 | 1062 |
| 1083 if (pointer.IsMouse()) { | 1063 if (pointer.IsMouse()) { |
| 1084 // If the mouse was moved towards the charms or the OS specific section, | 1064 // If the mouse was moved towards the charms or the OS specific section, |
| 1085 // the cursor may change from what the browser last set. Restore it here. | 1065 // the cursor may change from what the browser last set. Restore it here. |
| 1086 if (::GetCursor() != last_cursor_) | 1066 if (::GetCursor() != last_cursor_) |
| 1087 SetCursor(last_cursor_); | 1067 SetCursor(last_cursor_); |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 1103 | 1083 |
| 1104 // NOTE: From experimentation, it seems like Metro only sends a PointerPressed | 1084 // NOTE: From experimentation, it seems like Metro only sends a PointerPressed |
| 1105 // event for the first button pressed and the last button released in a sequence | 1085 // event for the first button pressed and the last button released in a sequence |
| 1106 // of mouse events. | 1086 // of mouse events. |
| 1107 // For example, a sequence of LEFT_DOWN, RIGHT_DOWN, LEFT_UP, RIGHT_UP results | 1087 // For example, a sequence of LEFT_DOWN, RIGHT_DOWN, LEFT_UP, RIGHT_UP results |
| 1108 // only in PointerPressed(LEFT)/PointerReleased(RIGHT) events. Intermediary | 1088 // only in PointerPressed(LEFT)/PointerReleased(RIGHT) events. Intermediary |
| 1109 // presses and releases are tracked in OnPointMoved(). | 1089 // presses and releases are tracked in OnPointMoved(). |
| 1110 HRESULT ChromeAppViewAsh::OnPointerPressed( | 1090 HRESULT ChromeAppViewAsh::OnPointerPressed( |
| 1111 winui::Core::ICoreWindow* sender, | 1091 winui::Core::ICoreWindow* sender, |
| 1112 winui::Core::IPointerEventArgs* args) { | 1092 winui::Core::IPointerEventArgs* args) { |
| 1093 if (!ui_channel_) | |
| 1094 return S_OK; | |
| 1095 | |
| 1113 PointerInfoHandler pointer(metro_dpi_scale_, win32_dpi_scale_); | 1096 PointerInfoHandler pointer(metro_dpi_scale_, win32_dpi_scale_); |
| 1114 HRESULT hr = pointer.Init(args); | 1097 HRESULT hr = pointer.Init(args); |
| 1115 if (FAILED(hr)) | 1098 if (FAILED(hr)) |
| 1116 return hr; | 1099 return hr; |
| 1117 | 1100 |
| 1118 if (pointer.IsMouse()) { | 1101 if (pointer.IsMouse()) { |
| 1119 mouse_down_flags_ = pointer.mouse_down_flags(); | 1102 mouse_down_flags_ = pointer.mouse_down_flags(); |
| 1120 SendMouseButton(pointer.x(), pointer.y(), 0, ui::ET_MOUSE_PRESSED, | 1103 SendMouseButton(pointer.x(), pointer.y(), 0, ui::ET_MOUSE_PRESSED, |
| 1121 mouse_down_flags_ | GetKeyboardEventFlags(), | 1104 mouse_down_flags_ | GetKeyboardEventFlags(), |
| 1122 pointer.changed_button(), pointer.is_horizontal_wheel()); | 1105 pointer.changed_button(), pointer.is_horizontal_wheel()); |
| 1123 } else { | 1106 } else { |
| 1124 DCHECK(pointer.IsTouch()); | 1107 DCHECK(pointer.IsTouch()); |
| 1125 ui_channel_->Send(new MetroViewerHostMsg_TouchDown(pointer.x(), | 1108 ui_channel_->Send(new MetroViewerHostMsg_TouchDown(pointer.x(), |
| 1126 pointer.y(), | 1109 pointer.y(), |
| 1127 pointer.timestamp(), | 1110 pointer.timestamp(), |
| 1128 pointer.pointer_id())); | 1111 pointer.pointer_id())); |
| 1129 } | 1112 } |
| 1130 return S_OK; | 1113 return S_OK; |
| 1131 } | 1114 } |
| 1132 | 1115 |
| 1133 HRESULT ChromeAppViewAsh::OnPointerReleased( | 1116 HRESULT ChromeAppViewAsh::OnPointerReleased( |
| 1134 winui::Core::ICoreWindow* sender, | 1117 winui::Core::ICoreWindow* sender, |
| 1135 winui::Core::IPointerEventArgs* args) { | 1118 winui::Core::IPointerEventArgs* args) { |
| 1119 if (!ui_channel_) | |
| 1120 return S_OK; | |
| 1121 | |
| 1136 PointerInfoHandler pointer(metro_dpi_scale_, win32_dpi_scale_); | 1122 PointerInfoHandler pointer(metro_dpi_scale_, win32_dpi_scale_); |
| 1137 HRESULT hr = pointer.Init(args); | 1123 HRESULT hr = pointer.Init(args); |
| 1138 if (FAILED(hr)) | 1124 if (FAILED(hr)) |
| 1139 return hr; | 1125 return hr; |
| 1140 | 1126 |
| 1141 if (pointer.IsMouse()) { | 1127 if (pointer.IsMouse()) { |
| 1142 mouse_down_flags_ = ui::EF_NONE; | 1128 mouse_down_flags_ = ui::EF_NONE; |
| 1143 SendMouseButton(pointer.x(), pointer.y(), 0, ui::ET_MOUSE_RELEASED, | 1129 SendMouseButton(pointer.x(), pointer.y(), 0, ui::ET_MOUSE_RELEASED, |
| 1144 static_cast<uint32>(pointer.changed_button()) | | 1130 static_cast<uint32>(pointer.changed_button()) | |
| 1145 GetKeyboardEventFlags(), | 1131 GetKeyboardEventFlags(), |
| 1146 pointer.changed_button(), | 1132 pointer.changed_button(), |
| 1147 pointer.is_horizontal_wheel()); | 1133 pointer.is_horizontal_wheel()); |
| 1148 } else { | 1134 } else { |
| 1149 DCHECK(pointer.IsTouch()); | 1135 DCHECK(pointer.IsTouch()); |
| 1150 ui_channel_->Send(new MetroViewerHostMsg_TouchUp(pointer.x(), | 1136 ui_channel_->Send(new MetroViewerHostMsg_TouchUp(pointer.x(), |
| 1151 pointer.y(), | 1137 pointer.y(), |
| 1152 pointer.timestamp(), | 1138 pointer.timestamp(), |
| 1153 pointer.pointer_id())); | 1139 pointer.pointer_id())); |
| 1154 } | 1140 } |
| 1155 return S_OK; | 1141 return S_OK; |
| 1156 } | 1142 } |
| 1157 | 1143 |
| 1158 HRESULT ChromeAppViewAsh::OnWheel( | 1144 HRESULT ChromeAppViewAsh::OnWheel( |
| 1159 winui::Core::ICoreWindow* sender, | 1145 winui::Core::ICoreWindow* sender, |
| 1160 winui::Core::IPointerEventArgs* args) { | 1146 winui::Core::IPointerEventArgs* args) { |
| 1147 if (!ui_channel_) | |
| 1148 return S_OK; | |
| 1149 | |
| 1161 PointerInfoHandler pointer(metro_dpi_scale_, win32_dpi_scale_); | 1150 PointerInfoHandler pointer(metro_dpi_scale_, win32_dpi_scale_); |
| 1162 HRESULT hr = pointer.Init(args); | 1151 HRESULT hr = pointer.Init(args); |
| 1163 if (FAILED(hr)) | 1152 if (FAILED(hr)) |
| 1164 return hr; | 1153 return hr; |
| 1165 DCHECK(pointer.IsMouse()); | 1154 DCHECK(pointer.IsMouse()); |
| 1166 SendMouseButton(pointer.x(), pointer.y(), pointer.wheel_delta(), | 1155 SendMouseButton(pointer.x(), pointer.y(), pointer.wheel_delta(), |
| 1167 ui::ET_MOUSEWHEEL, GetKeyboardEventFlags(), ui::EF_NONE, | 1156 ui::ET_MOUSEWHEEL, GetKeyboardEventFlags(), ui::EF_NONE, |
| 1168 pointer.is_horizontal_wheel()); | 1157 pointer.is_horizontal_wheel()); |
| 1169 return S_OK; | 1158 return S_OK; |
| 1170 } | 1159 } |
| 1171 | 1160 |
| 1172 HRESULT ChromeAppViewAsh::OnKeyDown( | 1161 HRESULT ChromeAppViewAsh::OnKeyDown( |
| 1173 winui::Core::ICoreWindow* sender, | 1162 winui::Core::ICoreWindow* sender, |
| 1174 winui::Core::IKeyEventArgs* args) { | 1163 winui::Core::IKeyEventArgs* args) { |
| 1164 if (!ui_channel_) | |
| 1165 return S_OK; | |
| 1166 | |
| 1175 winsys::VirtualKey virtual_key; | 1167 winsys::VirtualKey virtual_key; |
| 1176 HRESULT hr = args->get_VirtualKey(&virtual_key); | 1168 HRESULT hr = args->get_VirtualKey(&virtual_key); |
| 1177 if (FAILED(hr)) | 1169 if (FAILED(hr)) |
| 1178 return hr; | 1170 return hr; |
| 1179 winui::Core::CorePhysicalKeyStatus status; | 1171 winui::Core::CorePhysicalKeyStatus status; |
| 1180 hr = args->get_KeyStatus(&status); | 1172 hr = args->get_KeyStatus(&status); |
| 1181 if (FAILED(hr)) | 1173 if (FAILED(hr)) |
| 1182 return hr; | 1174 return hr; |
| 1183 | 1175 |
| 1184 ui_channel_->Send(new MetroViewerHostMsg_KeyDown(virtual_key, | 1176 ui_channel_->Send(new MetroViewerHostMsg_KeyDown(virtual_key, |
| 1185 status.RepeatCount, | 1177 status.RepeatCount, |
| 1186 status.ScanCode, | 1178 status.ScanCode, |
| 1187 GetKeyboardEventFlags())); | 1179 GetKeyboardEventFlags())); |
| 1188 return S_OK; | 1180 return S_OK; |
| 1189 } | 1181 } |
| 1190 | 1182 |
| 1191 HRESULT ChromeAppViewAsh::OnKeyUp( | 1183 HRESULT ChromeAppViewAsh::OnKeyUp( |
| 1192 winui::Core::ICoreWindow* sender, | 1184 winui::Core::ICoreWindow* sender, |
| 1193 winui::Core::IKeyEventArgs* args) { | 1185 winui::Core::IKeyEventArgs* args) { |
| 1186 if (!ui_channel_) | |
| 1187 return S_OK; | |
| 1188 | |
| 1194 winsys::VirtualKey virtual_key; | 1189 winsys::VirtualKey virtual_key; |
| 1195 HRESULT hr = args->get_VirtualKey(&virtual_key); | 1190 HRESULT hr = args->get_VirtualKey(&virtual_key); |
| 1196 if (FAILED(hr)) | 1191 if (FAILED(hr)) |
| 1197 return hr; | 1192 return hr; |
| 1198 winui::Core::CorePhysicalKeyStatus status; | 1193 winui::Core::CorePhysicalKeyStatus status; |
| 1199 hr = args->get_KeyStatus(&status); | 1194 hr = args->get_KeyStatus(&status); |
| 1200 if (FAILED(hr)) | 1195 if (FAILED(hr)) |
| 1201 return hr; | 1196 return hr; |
| 1202 | 1197 |
| 1203 ui_channel_->Send(new MetroViewerHostMsg_KeyUp(virtual_key, | 1198 ui_channel_->Send(new MetroViewerHostMsg_KeyUp(virtual_key, |
| 1204 status.RepeatCount, | 1199 status.RepeatCount, |
| 1205 status.ScanCode, | 1200 status.ScanCode, |
| 1206 GetKeyboardEventFlags())); | 1201 GetKeyboardEventFlags())); |
| 1207 return S_OK; | 1202 return S_OK; |
| 1208 } | 1203 } |
| 1209 | 1204 |
| 1210 HRESULT ChromeAppViewAsh::OnAcceleratorKeyDown( | 1205 HRESULT ChromeAppViewAsh::OnAcceleratorKeyDown( |
| 1211 winui::Core::ICoreDispatcher* sender, | 1206 winui::Core::ICoreDispatcher* sender, |
| 1212 winui::Core::IAcceleratorKeyEventArgs* args) { | 1207 winui::Core::IAcceleratorKeyEventArgs* args) { |
| 1208 if (!ui_channel_) | |
| 1209 return S_OK; | |
| 1210 | |
| 1213 winsys::VirtualKey virtual_key; | 1211 winsys::VirtualKey virtual_key; |
| 1214 HRESULT hr = args->get_VirtualKey(&virtual_key); | 1212 HRESULT hr = args->get_VirtualKey(&virtual_key); |
| 1215 if (FAILED(hr)) | 1213 if (FAILED(hr)) |
| 1216 return hr; | 1214 return hr; |
| 1217 winui::Core::CorePhysicalKeyStatus status; | 1215 winui::Core::CorePhysicalKeyStatus status; |
| 1218 hr = args->get_KeyStatus(&status); | 1216 hr = args->get_KeyStatus(&status); |
| 1219 if (FAILED(hr)) | 1217 if (FAILED(hr)) |
| 1220 return hr; | 1218 return hr; |
| 1221 | 1219 |
| 1222 winui::Core::CoreAcceleratorKeyEventType event_type; | 1220 winui::Core::CoreAcceleratorKeyEventType event_type; |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1257 | 1255 |
| 1258 default: | 1256 default: |
| 1259 break; | 1257 break; |
| 1260 } | 1258 } |
| 1261 return S_OK; | 1259 return S_OK; |
| 1262 } | 1260 } |
| 1263 | 1261 |
| 1264 HRESULT ChromeAppViewAsh::OnCharacterReceived( | 1262 HRESULT ChromeAppViewAsh::OnCharacterReceived( |
| 1265 winui::Core::ICoreWindow* sender, | 1263 winui::Core::ICoreWindow* sender, |
| 1266 winui::Core::ICharacterReceivedEventArgs* args) { | 1264 winui::Core::ICharacterReceivedEventArgs* args) { |
| 1265 if (!ui_channel_) | |
| 1266 return S_OK; | |
| 1267 | |
| 1267 unsigned int char_code = 0; | 1268 unsigned int char_code = 0; |
| 1268 HRESULT hr = args->get_KeyCode(&char_code); | 1269 HRESULT hr = args->get_KeyCode(&char_code); |
| 1269 if (FAILED(hr)) | 1270 if (FAILED(hr)) |
| 1270 return hr; | 1271 return hr; |
| 1271 | 1272 |
| 1272 winui::Core::CorePhysicalKeyStatus status; | 1273 winui::Core::CorePhysicalKeyStatus status; |
| 1273 hr = args->get_KeyStatus(&status); | 1274 hr = args->get_KeyStatus(&status); |
| 1274 if (FAILED(hr)) | 1275 if (FAILED(hr)) |
| 1275 return hr; | 1276 return hr; |
| 1276 | 1277 |
| 1277 ui_channel_->Send(new MetroViewerHostMsg_Character(char_code, | 1278 ui_channel_->Send(new MetroViewerHostMsg_Character(char_code, |
| 1278 status.RepeatCount, | 1279 status.RepeatCount, |
| 1279 status.ScanCode, | 1280 status.ScanCode, |
| 1280 GetKeyboardEventFlags())); | 1281 GetKeyboardEventFlags())); |
| 1281 return S_OK; | 1282 return S_OK; |
| 1282 } | 1283 } |
| 1283 | 1284 |
| 1284 HRESULT ChromeAppViewAsh::OnWindowActivated( | 1285 HRESULT ChromeAppViewAsh::OnWindowActivated( |
| 1285 winui::Core::ICoreWindow* sender, | 1286 winui::Core::ICoreWindow* sender, |
| 1286 winui::Core::IWindowActivatedEventArgs* args) { | 1287 winui::Core::IWindowActivatedEventArgs* args) { |
| 1288 if (!ui_channel_) | |
| 1289 return S_OK; | |
| 1290 | |
| 1287 if (args) { | 1291 if (args) { |
| 1288 winui::Core::CoreWindowActivationState state; | 1292 winui::Core::CoreWindowActivationState state; |
| 1289 HRESULT hr = args->get_WindowActivationState(&state); | 1293 HRESULT hr = args->get_WindowActivationState(&state); |
| 1290 if (FAILED(hr)) | 1294 if (FAILED(hr)) |
| 1291 return hr; | 1295 return hr; |
| 1292 | 1296 |
| 1293 // Treat both full activation (Ash was reopened from the Start Screen or | 1297 // Treat both full activation (Ash was reopened from the Start Screen or |
| 1294 // from any other Metro entry point in Windows) and pointer activation | 1298 // from any other Metro entry point in Windows) and pointer activation |
| 1295 // (user clicked back in Ash after using another app on another monitor) | 1299 // (user clicked back in Ash after using another app on another monitor) |
| 1296 // the same. | 1300 // the same. |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1351 ui_loop_.PostTask(FROM_HERE, | 1355 ui_loop_.PostTask(FROM_HERE, |
| 1352 base::Bind(&ChromeAppViewAsh::OnNavigateToUrl, | 1356 base::Bind(&ChromeAppViewAsh::OnNavigateToUrl, |
| 1353 base::Unretained(this), | 1357 base::Unretained(this), |
| 1354 actual_url)); | 1358 actual_url)); |
| 1355 return S_OK; | 1359 return S_OK; |
| 1356 } | 1360 } |
| 1357 | 1361 |
| 1358 HRESULT ChromeAppViewAsh::OnEdgeGestureCompleted( | 1362 HRESULT ChromeAppViewAsh::OnEdgeGestureCompleted( |
| 1359 winui::Input::IEdgeGesture* gesture, | 1363 winui::Input::IEdgeGesture* gesture, |
| 1360 winui::Input::IEdgeGestureEventArgs* args) { | 1364 winui::Input::IEdgeGestureEventArgs* args) { |
| 1361 ui_channel_->Send(new MetroViewerHostMsg_EdgeGesture()); | 1365 ui_channel_->Send(new MetroViewerHostMsg_EdgeGesture()); |
|
scottmg
2014/09/24 19:33:35
does this need if guarding now too?
ananta
2014/09/24 19:57:18
Done.
| |
| 1362 return S_OK; | 1366 return S_OK; |
| 1363 } | 1367 } |
| 1364 | 1368 |
| 1365 void ChromeAppViewAsh::OnSearchRequest(const base::string16& search_string) { | 1369 void ChromeAppViewAsh::OnSearchRequest(const base::string16& search_string) { |
| 1366 DCHECK(ui_channel_); | 1370 DCHECK(ui_channel_); |
|
scottmg
2014/09/24 19:33:35
same
ananta
2014/09/24 19:57:17
Done.
| |
| 1367 ui_channel_->Send(new MetroViewerHostMsg_SearchRequest(search_string)); | 1371 ui_channel_->Send(new MetroViewerHostMsg_SearchRequest(search_string)); |
| 1368 } | 1372 } |
| 1369 | 1373 |
| 1370 void ChromeAppViewAsh::OnNavigateToUrl(const base::string16& url) { | 1374 void ChromeAppViewAsh::OnNavigateToUrl(const base::string16& url) { |
| 1371 DCHECK(ui_channel_); | 1375 DCHECK(ui_channel_); |
|
scottmg
2014/09/24 19:33:35
same
ananta
2014/09/24 19:57:17
Done. Thanks for catching these.
| |
| 1372 ui_channel_->Send(new MetroViewerHostMsg_OpenURL(url)); | 1376 ui_channel_->Send(new MetroViewerHostMsg_OpenURL(url)); |
| 1373 } | 1377 } |
| 1374 | 1378 |
| 1375 HRESULT ChromeAppViewAsh::OnSizeChanged(winui::Core::ICoreWindow* sender, | 1379 HRESULT ChromeAppViewAsh::OnSizeChanged(winui::Core::ICoreWindow* sender, |
| 1376 winui::Core::IWindowSizeChangedEventArgs* args) { | 1380 winui::Core::IWindowSizeChangedEventArgs* args) { |
| 1377 if (!window_) { | 1381 if (!window_) { |
| 1378 return S_OK; | 1382 return S_OK; |
| 1379 } | 1383 } |
| 1380 | 1384 |
| 1381 // winui::Core::IWindowSizeChangedEventArgs args->Size appears to return | 1385 // winui::Core::IWindowSizeChangedEventArgs args->Size appears to return |
| 1382 // scaled values under HiDPI. We will instead use GetWindowRect() which | 1386 // scaled values under HiDPI. We will instead use GetWindowRect() which |
| 1383 // should always return values in Pixels. | 1387 // should always return values in Pixels. |
| 1384 RECT rect = {0}; | 1388 RECT rect = {0}; |
| 1385 ::GetWindowRect(core_window_hwnd_, &rect); | 1389 ::GetWindowRect(core_window_hwnd_, &rect); |
| 1386 | 1390 |
| 1387 uint32 cx = static_cast<uint32>(rect.right - rect.left); | 1391 uint32 cx = static_cast<uint32>(rect.right - rect.left); |
| 1388 uint32 cy = static_cast<uint32>(rect.bottom - rect.top); | 1392 uint32 cy = static_cast<uint32>(rect.bottom - rect.top); |
| 1389 | 1393 |
| 1390 DVLOG(1) << "Window size changed: width=" << cx << ", height=" << cy; | 1394 DVLOG(1) << "Window size changed: width=" << cx << ", height=" << cy; |
| 1391 ui_channel_->Send(new MetroViewerHostMsg_WindowSizeChanged(cx, cy)); | 1395 ui_channel_->Send(new MetroViewerHostMsg_WindowSizeChanged(cx, cy)); |
| 1392 return S_OK; | 1396 return S_OK; |
| 1393 } | 1397 } |
| 1394 | 1398 |
| 1399 // static | |
| 1400 void CALLBACK ChromeAppViewAsh::StartChromeOSMode(HWND core_window, | |
| 1401 UINT message, | |
| 1402 UINT_PTR timer_id, | |
| 1403 DWORD time) { | |
| 1404 static int ms_elapsed = 0; | |
| 1405 if (!IPC::Channel::IsNamedServerInitialized( | |
| 1406 win8::kMetroViewerIPCChannelName) && ms_elapsed < 10000) { | |
| 1407 ms_elapsed += 100; | |
| 1408 return; | |
| 1409 } | |
| 1410 | |
| 1411 ::KillTimer(core_window, kChromeChannelPollTimerId); | |
| 1412 | |
| 1413 if (!IPC::Channel::IsNamedServerInitialized( | |
| 1414 win8::kMetroViewerIPCChannelName)) { | |
| 1415 DVLOG(1) << "Failed to connect to chrome channel : " | |
| 1416 << win8::kMetroViewerIPCChannelName; | |
| 1417 DVLOG(1) << "Exiting. Elapsed time :" << ms_elapsed; | |
| 1418 PostMessage(core_window, WM_CLOSE, 0, 0); | |
| 1419 return; | |
| 1420 } | |
| 1421 | |
| 1422 DVLOG(1) << "Found channel : " << win8::kMetroViewerIPCChannelName; | |
| 1423 | |
| 1424 DCHECK(g_instance_); | |
| 1425 DCHECK(g_ui_channel_listener); | |
| 1426 | |
| 1427 // In Aura mode we create an IPC channel to the browser, then ask it to | |
| 1428 // connect to us. | |
| 1429 g_instance_->ui_channel_ = | |
| 1430 IPC::ChannelProxy::Create(win8::kMetroViewerIPCChannelName, | |
| 1431 IPC::Channel::MODE_NAMED_CLIENT, | |
| 1432 g_ui_channel_listener, | |
| 1433 g_instance_->io_thread_->message_loop_proxy()); | |
| 1434 DVLOG(1) << "Created channel proxy"; | |
| 1435 | |
| 1436 // Upon receipt of the MetroViewerHostMsg_SetTargetSurface message the | |
| 1437 // browser will use D3D from the browser process to present to our Window. | |
| 1438 g_instance_->ui_channel_->Send(new MetroViewerHostMsg_SetTargetSurface( | |
| 1439 gfx::NativeViewId(core_window), | |
| 1440 g_instance_->win32_dpi_scale_)); | |
| 1441 DVLOG(1) << "ICoreWindow sent " << core_window; | |
| 1442 | |
| 1443 // Send an initial size message so that the Ash root window host gets sized | |
| 1444 // correctly. | |
| 1445 RECT rect = {0}; | |
| 1446 ::GetWindowRect(core_window, &rect); | |
| 1447 g_instance_->ui_channel_->Send( | |
| 1448 new MetroViewerHostMsg_WindowSizeChanged(rect.right - rect.left, | |
| 1449 rect.bottom - rect.top)); | |
| 1450 | |
| 1451 g_instance_->input_source_ = metro_driver::InputSource::Create(); | |
| 1452 if (g_instance_->input_source_) { | |
| 1453 g_instance_->input_source_->AddObserver(g_instance_); | |
| 1454 // Send an initial input source. | |
| 1455 g_instance_->OnInputSourceChanged(); | |
| 1456 } | |
| 1457 | |
| 1458 // Start receiving IME popup window notifications. | |
| 1459 metro_driver::AddImePopupObserver(g_instance_); | |
| 1460 | |
| 1461 DVLOG(1) << "Channel setup complete"; | |
| 1462 } | |
| 1463 | |
| 1395 /////////////////////////////////////////////////////////////////////////////// | 1464 /////////////////////////////////////////////////////////////////////////////// |
| 1396 | 1465 |
| 1397 ChromeAppViewFactory::ChromeAppViewFactory( | 1466 ChromeAppViewFactory::ChromeAppViewFactory( |
| 1398 winapp::Core::ICoreApplication* icore_app) { | 1467 winapp::Core::ICoreApplication* icore_app) { |
| 1399 mswr::ComPtr<winapp::Core::ICoreApplication> core_app(icore_app); | 1468 mswr::ComPtr<winapp::Core::ICoreApplication> core_app(icore_app); |
| 1400 mswr::ComPtr<winapp::Core::ICoreApplicationExit> app_exit; | 1469 mswr::ComPtr<winapp::Core::ICoreApplicationExit> app_exit; |
| 1401 CheckHR(core_app.As(&app_exit)); | 1470 CheckHR(core_app.As(&app_exit)); |
| 1402 globals.app_exit = app_exit.Detach(); | 1471 globals.app_exit = app_exit.Detach(); |
| 1403 } | 1472 } |
| 1404 | 1473 |
| 1405 IFACEMETHODIMP | 1474 IFACEMETHODIMP |
| 1406 ChromeAppViewFactory::CreateView(winapp::Core::IFrameworkView** view) { | 1475 ChromeAppViewFactory::CreateView(winapp::Core::IFrameworkView** view) { |
| 1407 *view = mswr::Make<ChromeAppViewAsh>().Detach(); | 1476 *view = mswr::Make<ChromeAppViewAsh>().Detach(); |
| 1408 return (*view) ? S_OK : E_OUTOFMEMORY; | 1477 return (*view) ? S_OK : E_OUTOFMEMORY; |
| 1409 } | 1478 } |
| OLD | NEW |