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 #include "ui/views/widget/desktop_aura/desktop_capture_client.h" 6 7 #include "ui/aura/root_window.h" 8 9 namespace views { 10 11 std::set<DesktopCaptureClient*> DesktopCaptureClient::live_capture_clients_; 12 13 DesktopCaptureClient::DesktopCaptureClient(aura::RootWindow* root_window) 14 : root_window_(root_window), 15 capture_window_(NULL) { 16 aura::client::SetCaptureClient(root_window_, this); 17 live_capture_clients_.insert(this); 18 } 19 20 DesktopCaptureClient::~DesktopCaptureClient() { 21 live_capture_clients_.erase(this); 22 aura::client::SetCaptureClient(root_window_, NULL); 23 } 24 25 void DesktopCaptureClient::SetCapture(aura::Window* window) { 26 if (capture_window_ == window) 27 return; 28 if (window) { 29 // If we're actually starting capture, then cancel any touches/gestures 30 // that aren't already locked to the new window, and transfer any on the 31 // old capture window to the new one. When capture is released we have no 32 // distinction between the touches/gestures that were in the window all 33 // along (and so shouldn't be canceled) and those that got moved, so 34 // just leave them all where they are. 35 for (std::set<DesktopCaptureClient*>::iterator it = 36 live_capture_clients_.begin(); it != live_capture_clients_.end(); 37 ++it) { 38 (*it)->root_window_->gesture_recognizer()->TransferEventsTo( 39 capture_window_, window); 40 } 41 } 42 aura::Window* old_capture_window = GetCaptureWindow(); 43 capture_window_ = window; 44 45 if (capture_window_) { 46 root_window_->SetNativeCapture(); 47 48 for (std::set<DesktopCaptureClient*>::iterator it = 49 live_capture_clients_.begin(); it != live_capture_clients_.end(); 50 ++it) { 51 if (*it != this) 52 (*it)->OnOtherCaptureClientTookCapture(); 53 } 54 } else { 55 root_window_->ReleaseNativeCapture(); 56 } 57 58 root_window_->UpdateCapture(old_capture_window, capture_window_); 59 } 60 61 void DesktopCaptureClient::ReleaseCapture(aura::Window* window) { 62 if (capture_window_ != window) 63 return; 64 SetCapture(NULL); 65 } 66 67 aura::Window* DesktopCaptureClient::GetCaptureWindow() { 68 for (std::set<DesktopCaptureClient*>::iterator it = 69 live_capture_clients_.begin(); it != live_capture_clients_.end(); 70 ++it) { 71 if ((*it)->capture_window_) 72 return (*it)->capture_window_; 73 } 74 return NULL; 75 } 76 77 void DesktopCaptureClient::OnOtherCaptureClientTookCapture() { 78 if (capture_window_ == NULL) { 79 // While RootWindow may not technically have capture, it will store state 80 // that needs to be cleared on capture changed regarding mouse up/down. 81 root_window_->ClearMouseHandlers(); 82 } 83 else { 84 SetCapture(NULL); 85 } 86 } 87 88 } // namespace views 89