Home | History | Annotate | Download | only in desktop_aura
      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