1// Copyright 2013 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/window.h"
8#include "ui/aura/window_event_dispatcher.h"
9#include "ui/aura/window_tree_host.h"
10
11namespace views {
12
13// static
14DesktopCaptureClient::CaptureClients*
15DesktopCaptureClient::capture_clients_ = NULL;
16
17DesktopCaptureClient::DesktopCaptureClient(aura::Window* root)
18    : root_(root),
19      capture_window_(NULL) {
20  if (!capture_clients_)
21    capture_clients_ = new CaptureClients;
22  capture_clients_->insert(this);
23  aura::client::SetCaptureClient(root, this);
24}
25
26DesktopCaptureClient::~DesktopCaptureClient() {
27  aura::client::SetCaptureClient(root_, NULL);
28  capture_clients_->erase(this);
29}
30
31void DesktopCaptureClient::SetCapture(aura::Window* new_capture_window) {
32  if (capture_window_ == new_capture_window)
33    return;
34
35  // We should only ever be told to capture a child of |root_|. Otherwise
36  // things are going to be really confused.
37  DCHECK(!new_capture_window ||
38         (new_capture_window->GetRootWindow() == root_));
39  DCHECK(!capture_window_ || capture_window_->GetRootWindow());
40
41  aura::Window* old_capture_window = capture_window_;
42
43  // If we're actually starting capture, then cancel any touches/gestures
44  // that aren't already locked to the new window, and transfer any on the
45  // old capture window to the new one.  When capture is released we have no
46  // distinction between the touches/gestures that were in the window all
47  // along (and so shouldn't be canceled) and those that got moved, so
48  // just leave them all where they are.
49  if (new_capture_window) {
50    ui::GestureRecognizer::Get()->TransferEventsTo(old_capture_window,
51        new_capture_window);
52  }
53
54  capture_window_ = new_capture_window;
55
56  aura::client::CaptureDelegate* delegate = root_->GetHost()->dispatcher();
57  delegate->UpdateCapture(old_capture_window, new_capture_window);
58
59  // Initiate native capture updating.
60  if (!capture_window_) {
61    delegate->ReleaseNativeCapture();
62  } else if (!old_capture_window) {
63    delegate->SetNativeCapture();
64
65    // Notify the other roots that we got capture. This is important so that
66    // they reset state.
67    CaptureClients capture_clients(*capture_clients_);
68    for (CaptureClients::iterator i = capture_clients.begin();
69         i != capture_clients.end(); ++i) {
70      if (*i != this) {
71        aura::client::CaptureDelegate* delegate =
72            (*i)->root_->GetHost()->dispatcher();
73        delegate->OnOtherRootGotCapture();
74      }
75    }
76  }  // else case is capture is remaining in our root, nothing to do.
77}
78
79void DesktopCaptureClient::ReleaseCapture(aura::Window* window) {
80  if (capture_window_ != window)
81    return;
82  SetCapture(NULL);
83}
84
85aura::Window* DesktopCaptureClient::GetCaptureWindow() {
86  return capture_window_;
87}
88
89aura::Window* DesktopCaptureClient::GetGlobalCaptureWindow() {
90  for (CaptureClients::iterator i = capture_clients_->begin();
91       i != capture_clients_->end(); ++i) {
92    if ((*i)->capture_window_)
93      return (*i)->capture_window_;
94  }
95  return NULL;
96}
97
98}  // namespace views
99