diff options
23 files changed, 205 insertions, 17 deletions
diff --git a/chrome/browser/metro_viewer/metro_viewer_process_host_win.cc b/chrome/browser/metro_viewer/metro_viewer_process_host_win.cc index 23dc1dd..a1b411e 100644 --- a/chrome/browser/metro_viewer/metro_viewer_process_host_win.cc +++ b/chrome/browser/metro_viewer/metro_viewer_process_host_win.cc @@ -40,6 +40,8 @@ bool MetroViewerProcessHost::OnMessageReceived(const IPC::Message& message) { IPC_MESSAGE_HANDLER(MetroViewerHostMsg_KeyDown, OnKeyDown) IPC_MESSAGE_HANDLER(MetroViewerHostMsg_KeyUp, OnKeyUp) IPC_MESSAGE_HANDLER(MetroViewerHostMsg_Character, OnChar) + IPC_MESSAGE_HANDLER(MetroViewerHostMsg_VisibilityChanged, + OnVisibilityChanged) IPC_MESSAGE_UNHANDLED(handled = false) IPC_END_MESSAGE_MAP() return handled; @@ -99,3 +101,8 @@ void MetroViewerProcessHost::OnChar(uint32 key_code, aura::RemoteRootWindowHostWin::Instance()->OnChar( key_code, repeat_count, scan_code, flags); } + +void MetroViewerProcessHost::OnVisibilityChanged(bool visible) { + aura::RemoteRootWindowHostWin::Instance()->OnVisibilityChanged( + visible); +} diff --git a/chrome/browser/metro_viewer/metro_viewer_process_host_win.h b/chrome/browser/metro_viewer/metro_viewer_process_host_win.h index 9d71524..f63a93d 100644 --- a/chrome/browser/metro_viewer/metro_viewer_process_host_win.h +++ b/chrome/browser/metro_viewer/metro_viewer_process_host_win.h @@ -49,6 +49,7 @@ class MetroViewerProcessHost : public IPC::Listener, uint32 repeat_count, uint32 scan_code, uint32 flags); + void OnVisibilityChanged(bool visible); scoped_ptr<IPC::ChannelProxy> channel_; diff --git a/chrome/browser/ui/aura/active_desktop_monitor.cc b/chrome/browser/ui/aura/active_desktop_monitor.cc new file mode 100644 index 0000000..65fee36 --- /dev/null +++ b/chrome/browser/ui/aura/active_desktop_monitor.cc @@ -0,0 +1,65 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/ui/aura/active_desktop_monitor.h" + +#include "ui/aura/env.h" +#include "ui/aura/root_window.h" + +#if defined(OS_LINUX) +#include "ui/views/widget/desktop_aura/desktop_root_window_host_linux.h" +#elif defined(OS_WIN) +#include "ui/views/widget/desktop_aura/desktop_root_window_host_win.h" +#endif + +// static +ActiveDesktopMonitor* ActiveDesktopMonitor::g_instance_ = NULL; + +ActiveDesktopMonitor::ActiveDesktopMonitor() + : last_activated_desktop_(chrome::HOST_DESKTOP_TYPE_NATIVE) { + DCHECK(!g_instance_); + g_instance_ = this; + aura::Env::GetInstance()->AddObserver(this); +} + +ActiveDesktopMonitor::~ActiveDesktopMonitor() { + DCHECK_EQ(g_instance_, this); + aura::Env::GetInstance()->RemoveObserver(this); + g_instance_ = NULL; +} + +// static +chrome::HostDesktopType ActiveDesktopMonitor::GetLastActivatedDesktopType() { + return g_instance_->last_activated_desktop_; +} + +// static +bool ActiveDesktopMonitor::IsDesktopWindow(aura::RootWindow* root_window) { + // Only windows hosted by a DesktopRootWindowHost implementation can be mapped + // back to a content Window. All others, therefore, must be the root window + // for an Ash display. +#if defined(OS_WIN) + return views::DesktopRootWindowHostWin::GetContentWindowForHWND( + root_window->GetAcceleratedWidget()) != NULL; +#elif defined(OS_LINUX) + return views::DesktopRootWindowHostLinux::GetContentWindowForXID( + root_window->GetAcceleratedWidget()) != NULL; +#else + NOTREACHED(); + return true; +#endif +} + +void ActiveDesktopMonitor::OnWindowInitialized(aura::Window* window) {} + +void ActiveDesktopMonitor::OnRootWindowActivated( + aura::RootWindow* root_window) { + if (IsDesktopWindow(root_window)) + last_activated_desktop_ = chrome::HOST_DESKTOP_TYPE_NATIVE; + else + last_activated_desktop_ = chrome::HOST_DESKTOP_TYPE_ASH; + DVLOG(1) << __FUNCTION__ + << (last_activated_desktop_ == chrome::HOST_DESKTOP_TYPE_NATIVE ? + " native" : " ash") << " desktop activated."; +} diff --git a/chrome/browser/ui/aura/active_desktop_monitor.h b/chrome/browser/ui/aura/active_desktop_monitor.h new file mode 100644 index 0000000..ff63984 --- /dev/null +++ b/chrome/browser/ui/aura/active_desktop_monitor.h @@ -0,0 +1,40 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_UI_AURA_ACTIVE_DESKTOP_MONITOR_H_ +#define CHROME_BROWSER_UI_AURA_ACTIVE_DESKTOP_MONITOR_H_ + +#include "base/basictypes.h" +#include "base/compiler_specific.h" +#include "chrome/browser/ui/host_desktop.h" +#include "ui/aura/env_observer.h" + +// Tracks the most-recently activated host desktop type by observing +// RootWindowHost activations. +class ActiveDesktopMonitor : public aura::EnvObserver { + public: + ActiveDesktopMonitor(); + virtual ~ActiveDesktopMonitor(); + + // Returns the host desktop type of the most-recently activated + // RootWindowHost. This desktop type may no longer exist (e.g., the Ash + // desktop may have closed since being active, and no RWHs on the native + // desktop have yet been activated). + static chrome::HostDesktopType GetLastActivatedDesktopType(); + + private: + // Returns true if |root_window| is hosted by a DesktopRootWindowHost. + static bool IsDesktopWindow(aura::RootWindow* root_window); + + // aura::EnvObserver methods. + virtual void OnWindowInitialized(aura::Window* window) OVERRIDE; + virtual void OnRootWindowActivated(aura::RootWindow* root_window) OVERRIDE; + + static ActiveDesktopMonitor* g_instance_; + chrome::HostDesktopType last_activated_desktop_; + + DISALLOW_COPY_AND_ASSIGN(ActiveDesktopMonitor); +}; + +#endif // CHROME_BROWSER_UI_AURA_ACTIVE_DESKTOP_MONITOR_H_ diff --git a/chrome/browser/ui/aura/chrome_browser_main_extra_parts_aura.cc b/chrome/browser/ui/aura/chrome_browser_main_extra_parts_aura.cc index 4c5dff5..21387c8 100644 --- a/chrome/browser/ui/aura/chrome_browser_main_extra_parts_aura.cc +++ b/chrome/browser/ui/aura/chrome_browser_main_extra_parts_aura.cc @@ -6,6 +6,7 @@ #include "chrome/browser/chrome_browser_main.h" #include "chrome/browser/toolkit_extra_parts.h" +#include "chrome/browser/ui/aura/active_desktop_monitor.h" #include "chrome/browser/ui/aura/stacking_client_aura.h" #include "ui/aura/env.h" #include "ui/gfx/screen.h" @@ -32,6 +33,7 @@ ChromeBrowserMainExtraPartsAura::~ChromeBrowserMainExtraPartsAura() { void ChromeBrowserMainExtraPartsAura::PreProfileInit() { #if !defined(OS_CHROMEOS) #if defined(USE_ASH) + active_desktop_monitor_.reset(new ActiveDesktopMonitor); if (!chrome::ShouldOpenAshOnStartup()) #endif { @@ -50,6 +52,7 @@ void ChromeBrowserMainExtraPartsAura::PreProfileInit() { void ChromeBrowserMainExtraPartsAura::PostMainMessageLoopRun() { stacking_client_.reset(); + active_desktop_monitor_.reset(); // aura::Env instance is deleted in BrowserProcessImpl::StartTearDown // after the metrics service is deleted. diff --git a/chrome/browser/ui/aura/chrome_browser_main_extra_parts_aura.h b/chrome/browser/ui/aura/chrome_browser_main_extra_parts_aura.h index 3f0784a..4bb8cfe 100644 --- a/chrome/browser/ui/aura/chrome_browser_main_extra_parts_aura.h +++ b/chrome/browser/ui/aura/chrome_browser_main_extra_parts_aura.h @@ -16,6 +16,8 @@ class StackingClient; } } +class ActiveDesktopMonitor; + class ChromeBrowserMainExtraPartsAura : public ChromeBrowserMainExtraParts { public: ChromeBrowserMainExtraPartsAura(); @@ -27,6 +29,7 @@ class ChromeBrowserMainExtraPartsAura : public ChromeBrowserMainExtraParts { private: scoped_ptr<aura::client::StackingClient> stacking_client_; + scoped_ptr<ActiveDesktopMonitor> active_desktop_monitor_; DISALLOW_COPY_AND_ASSIGN(ChromeBrowserMainExtraPartsAura); }; diff --git a/chrome/browser/ui/host_desktop.cc b/chrome/browser/ui/host_desktop.cc index e2c34bb..f7f7c65 100644 --- a/chrome/browser/ui/host_desktop.cc +++ b/chrome/browser/ui/host_desktop.cc @@ -8,14 +8,11 @@ #include <windows.h> #endif +#include "ash/shell.h" #include "chrome/browser/ui/ash/ash_util.h" +#include "chrome/browser/ui/aura/active_desktop_monitor.h" #include "chrome/browser/ui/browser_list_impl.h" -#if defined(OS_WIN) -#include "ash/shell.h" -#include "ui/aura/root_window.h" -#endif - namespace chrome { namespace { @@ -79,16 +76,19 @@ HostDesktopType GetHostDesktopTypeForBrowser(const Browser* browser) { } HostDesktopType GetActiveDesktop() { -#if defined(OS_WIN) && defined(USE_ASH) - if (ash::Shell::HasInstance()) { - HWND active_window = GetActiveWindow(); - typedef ash::Shell::RootWindowList RootWindowList; - RootWindowList roots(ash::Shell::GetAllRootWindows()); - for (RootWindowList::const_iterator i = roots.begin(); i != roots.end(); - ++i) { - if ((*i)->GetAcceleratedWidget() == active_window) - return HOST_DESKTOP_TYPE_ASH; - } +#if defined(USE_ASH) && !defined(OS_CHROMEOS) + // The Ash desktop is considered active if a non-desktop RootWindow was last + // activated and the Ash desktop is still open. As it is, the Ash desktop + // will be considered the last active if a user switches from metro Chrome to + // the Windows desktop but doesn't activate any Chrome windows there (e.g., + // by clicking on one or otherwise giving one focus). Consider finding a way + // to detect that the Windows desktop has been activated so that the native + // desktop can be considered active once the user switches to it if its + // BrowserList isn't empty. + if ((ActiveDesktopMonitor::GetLastActivatedDesktopType() == + chrome::HOST_DESKTOP_TYPE_ASH) && + ash::Shell::HasInstance()) { + return HOST_DESKTOP_TYPE_ASH; } #endif return HOST_DESKTOP_TYPE_NATIVE; diff --git a/chrome/browser/ui/host_desktop.h b/chrome/browser/ui/host_desktop.h index b0f188b..9b2dc75 100644 --- a/chrome/browser/ui/host_desktop.h +++ b/chrome/browser/ui/host_desktop.h @@ -47,6 +47,8 @@ HostDesktopType GetHostDesktopTypeForNativeWindow( gfx::NativeWindow native_window); HostDesktopType GetHostDesktopTypeForBrowser(const Browser* browser); +// Returns the type of host desktop most likely to be in use. This is the one +// most recently activated by the user. HostDesktopType GetActiveDesktop(); } // namespace chrome diff --git a/chrome/chrome_browser_ui.gypi b/chrome/chrome_browser_ui.gypi index 489e3cf..e3104ce 100644 --- a/chrome/chrome_browser_ui.gypi +++ b/chrome/chrome_browser_ui.gypi @@ -168,6 +168,8 @@ 'browser/ui/ash/volume_controller_chromeos.h', 'browser/ui/ash/window_positioner.cc', 'browser/ui/ash/window_positioner.h', + 'browser/ui/aura/active_desktop_monitor.cc', + 'browser/ui/aura/active_desktop_monitor.h', 'browser/ui/aura/chrome_browser_main_extra_parts_aura.cc', 'browser/ui/aura/chrome_browser_main_extra_parts_aura.h', 'browser/ui/aura/stacking_client_aura.cc', diff --git a/ui/aura/env.cc b/ui/aura/env.cc index b967ed7..d46783f 100644 --- a/ui/aura/env.cc +++ b/ui/aura/env.cc @@ -96,6 +96,11 @@ MessageLoop::Dispatcher* Env::GetDispatcher() { } #endif +void Env::RootWindowActivated(RootWindow* root_window) { + FOR_EACH_OBSERVER(EnvObserver, observers_, + OnRootWindowActivated(root_window)); +} + //////////////////////////////////////////////////////////////////////////////// // Env, private: diff --git a/ui/aura/env.h b/ui/aura/env.h index 661af25..d6db1ed 100644 --- a/ui/aura/env.h +++ b/ui/aura/env.h @@ -20,6 +20,7 @@ namespace aura { class EnvObserver; +class RootWindow; class Window; #if !defined(USE_X11) @@ -78,6 +79,9 @@ class AURA_EXPORT Env : public ui::EventTarget { MessageLoop::Dispatcher* GetDispatcher(); #endif + // Invoked by RootWindow when its host is activated. + void RootWindowActivated(RootWindow* root_window); + private: friend class Window; diff --git a/ui/aura/env_observer.h b/ui/aura/env_observer.h index fd41c6d..3e0f76e 100644 --- a/ui/aura/env_observer.h +++ b/ui/aura/env_observer.h @@ -9,6 +9,7 @@ namespace aura { +class RootWindow; class Window; class AURA_EXPORT EnvObserver { @@ -16,6 +17,9 @@ class AURA_EXPORT EnvObserver { // Called when |window| has been initialized. virtual void OnWindowInitialized(Window* window) = 0; + // Called when a RootWindow's host is activated. + virtual void OnRootWindowActivated(RootWindow* root_window) {} + // Called right before Env is destroyed. virtual void OnWillDestroyEnv() {} diff --git a/ui/aura/remote_root_window_host_win.cc b/ui/aura/remote_root_window_host_win.cc index 918ac4d..d808cdf 100644 --- a/ui/aura/remote_root_window_host_win.cc +++ b/ui/aura/remote_root_window_host_win.cc @@ -10,7 +10,6 @@ #include "base/message_loop.h" #include "ui/aura/client/capture_client.h" -#include "ui/aura/env.h" #include "ui/aura/root_window.h" #include "ui/base/cursor/cursor_loader_win.h" #include "ui/base/events/event.h" @@ -200,4 +199,9 @@ void RemoteRootWindowHostWin::OnChar(uint32 key_code, delegate_->OnHostKeyEvent(&event); } +void RemoteRootWindowHostWin::OnVisibilityChanged(bool visible) { + if (visible) + delegate_->OnHostActivated(); +} + } // namespace aura diff --git a/ui/aura/remote_root_window_host_win.h b/ui/aura/remote_root_window_host_win.h index 79b6c4c..92c1292 100644 --- a/ui/aura/remote_root_window_host_win.h +++ b/ui/aura/remote_root_window_host_win.h @@ -38,6 +38,7 @@ class AURA_EXPORT RemoteRootWindowHostWin : public RootWindowHost { uint32 repeat_count, uint32 scan_code, uint32 flags); + void OnVisibilityChanged(bool visible); private: RemoteRootWindowHostWin(const gfx::Rect& bounds); diff --git a/ui/aura/root_window.cc b/ui/aura/root_window.cc index c398125..d734807 100644 --- a/ui/aura/root_window.cc +++ b/ui/aura/root_window.cc @@ -903,6 +903,10 @@ bool RootWindow::OnHostTouchEvent(ui::TouchEvent* event) { return ProcessGestures(gestures.get()) ? true : handled; } +void RootWindow::OnHostActivated() { + Env::GetInstance()->RootWindowActivated(this); +} + void RootWindow::OnHostLostWindowCapture() { Window* capture_window = client::GetCaptureWindow(this); if (capture_window && capture_window->GetRootWindow() == this) diff --git a/ui/aura/root_window.h b/ui/aura/root_window.h index 5f7af88..86c15c9 100644 --- a/ui/aura/root_window.h +++ b/ui/aura/root_window.h @@ -330,6 +330,7 @@ class AURA_EXPORT RootWindow : public ui::CompositorDelegate, virtual bool OnHostMouseEvent(ui::MouseEvent* event) OVERRIDE; virtual bool OnHostScrollEvent(ui::ScrollEvent* event) OVERRIDE; virtual bool OnHostTouchEvent(ui::TouchEvent* event) OVERRIDE; + virtual void OnHostActivated() OVERRIDE; virtual void OnHostLostWindowCapture() OVERRIDE; virtual void OnHostLostMouseGrab() OVERRIDE; virtual void OnHostPaint() OVERRIDE; diff --git a/ui/aura/root_window_host_delegate.h b/ui/aura/root_window_host_delegate.h index 7ca3dd7..f45c0fb 100644 --- a/ui/aura/root_window_host_delegate.h +++ b/ui/aura/root_window_host_delegate.h @@ -32,6 +32,9 @@ class AURA_EXPORT RootWindowHostDelegate { virtual bool OnHostScrollEvent(ui::ScrollEvent* event) = 0; virtual bool OnHostTouchEvent(ui::TouchEvent* event) = 0; + // Called when the windowing system activates the window. + virtual void OnHostActivated() = 0; + // Called when system focus is changed to another window. virtual void OnHostLostWindowCapture() = 0; diff --git a/ui/aura/root_window_host_win.cc b/ui/aura/root_window_host_win.cc index f21170c..cb1cd7d 100644 --- a/ui/aura/root_window_host_win.cc +++ b/ui/aura/root_window_host_win.cc @@ -10,7 +10,6 @@ #include "base/message_loop.h" #include "ui/aura/client/capture_client.h" -#include "ui/aura/env.h" #include "ui/aura/root_window.h" #include "ui/base/cursor/cursor_loader_win.h" #include "ui/base/events/event.h" @@ -257,6 +256,14 @@ LRESULT RootWindowHostWin::OnCaptureChanged(UINT message, return 0; } +LRESULT RootWindowHostWin::OnNCActivate(UINT message, + WPARAM w_param, + LPARAM l_param) { + if (!!w_param) + delegate_->OnHostActivated(); + return DefWindowProc(hwnd(), message, w_param, l_param); +} + void RootWindowHostWin::OnPaint(HDC dc) { delegate_->OnHostPaint(); ValidateRect(hwnd(), NULL); diff --git a/ui/aura/root_window_host_win.h b/ui/aura/root_window_host_win.h index 9dfa05c..96f3d62 100644 --- a/ui/aura/root_window_host_win.h +++ b/ui/aura/root_window_host_win.h @@ -60,6 +60,7 @@ class RootWindowHostWin : public RootWindowHost, public ui::WindowImpl { MESSAGE_HANDLER_EX(WM_CHAR, OnKeyEvent) MESSAGE_HANDLER_EX(WM_SYSCHAR, OnKeyEvent) MESSAGE_HANDLER_EX(WM_IME_CHAR, OnKeyEvent) + MESSAGE_HANDLER_EX(WM_NCACTIVATE, OnNCActivate) MSG_WM_CLOSE(OnClose) MSG_WM_PAINT(OnPaint) @@ -70,6 +71,7 @@ class RootWindowHostWin : public RootWindowHost, public ui::WindowImpl { LRESULT OnKeyEvent(UINT message, WPARAM w_param, LPARAM l_param); LRESULT OnMouseRange(UINT message, WPARAM w_param, LPARAM l_param); LRESULT OnCaptureChanged(UINT message, WPARAM w_param, LPARAM l_param); + LRESULT OnNCActivate(UINT message, WPARAM w_param, LPARAM l_param); void OnPaint(HDC dc); void OnSize(UINT param, const CSize& size); diff --git a/ui/metro_viewer/metro_viewer_messages.h b/ui/metro_viewer/metro_viewer_messages.h index 1a43e4c..e141c34 100644 --- a/ui/metro_viewer/metro_viewer_messages.h +++ b/ui/metro_viewer/metro_viewer_messages.h @@ -48,3 +48,6 @@ IPC_MESSAGE_CONTROL4(MetroViewerHostMsg_Character, uint32, /* repeat count */ uint32, /* scan code */ uint32 /* key state */); +// Informs the browser that the visibiliy of the viewer has changed. +IPC_MESSAGE_CONTROL1(MetroViewerHostMsg_VisibilityChanged, + bool /* visible */); diff --git a/ui/views/widget/desktop_aura/desktop_root_window_host_win.cc b/ui/views/widget/desktop_aura/desktop_root_window_host_win.cc index 7952ebc..9c4c6c1 100644 --- a/ui/views/widget/desktop_aura/desktop_root_window_host_win.cc +++ b/ui/views/widget/desktop_aura/desktop_root_window_host_win.cc @@ -569,6 +569,8 @@ void DesktopRootWindowHostWin::HandleAppDeactivated() { } void DesktopRootWindowHostWin::HandleActivationChanged(bool active) { + if (active) + root_window_host_delegate_->OnHostActivated(); native_widget_delegate_->OnNativeWidgetActivationChanged(active); } diff --git a/win8/metro_driver/chrome_app_view_ash.cc b/win8/metro_driver/chrome_app_view_ash.cc index e9a9363..2214185 100644 --- a/win8/metro_driver/chrome_app_view_ash.cc +++ b/win8/metro_driver/chrome_app_view_ash.cc @@ -40,6 +40,10 @@ typedef winfoundtn::ITypedEventHandler< winui::Core::CoreWindow*, winui::Core::CharacterReceivedEventArgs*> CharEventHandler; +typedef winfoundtn::ITypedEventHandler< + winui::Core::CoreWindow*, + winui::Core::VisibilityChangedEventArgs*> VisibilityChangedHandler; + // This function is exported by chrome.exe. typedef int (__cdecl *BreakpadExceptionHandler)(EXCEPTION_POINTERS* info); @@ -283,6 +287,11 @@ ChromeAppViewAsh::SetWindow(winui::Core::ICoreWindow* window) { &character_received_token_); CheckHR(hr); + hr = window_->add_VisibilityChanged(mswr::Callback<VisibilityChangedHandler>( + this, &ChromeAppViewAsh::OnVisibilityChanged).Get(), + &visibility_changed_token_); + CheckHR(hr); + // By initializing the direct 3D swap chain with the corewindow // we can now directly blit to it from the browser process. direct3d_helper_.Initialize(window); @@ -488,6 +497,18 @@ HRESULT ChromeAppViewAsh::OnCharacterReceived( return S_OK; } +HRESULT ChromeAppViewAsh::OnVisibilityChanged( + winui::Core::ICoreWindow* sender, + winui::Core::IVisibilityChangedEventArgs* args) { + boolean visible = false; + HRESULT hr = args->get_Visible(&visible); + if (FAILED(hr)) + return hr; + + ui_channel_->Send(new MetroViewerHostMsg_VisibilityChanged(!!visible)); + return S_OK; +} + /////////////////////////////////////////////////////////////////////////////// diff --git a/win8/metro_driver/chrome_app_view_ash.h b/win8/metro_driver/chrome_app_view_ash.h index 886510c..1906297 100644 --- a/win8/metro_driver/chrome_app_view_ash.h +++ b/win8/metro_driver/chrome_app_view_ash.h @@ -56,6 +56,9 @@ class ChromeAppViewAsh HRESULT OnCharacterReceived(winui::Core::ICoreWindow* sender, winui::Core::ICharacterReceivedEventArgs* args); + HRESULT OnVisibilityChanged(winui::Core::ICoreWindow* sender, + winui::Core::IVisibilityChangedEventArgs* args); + mswr::ComPtr<winui::Core::ICoreWindow> window_; mswr::ComPtr<winapp::Core::ICoreApplicationView> view_; EventRegistrationToken activated_token_; @@ -66,6 +69,7 @@ class ChromeAppViewAsh EventRegistrationToken keydown_token_; EventRegistrationToken keyup_token_; EventRegistrationToken character_received_token_; + EventRegistrationToken visibility_changed_token_; metro_driver::Direct3DHelper direct3d_helper_; |