Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(162)

Side by Side Diff: ui/snapshot/screenshot_grabber.cc

Issue 2167613003: Hide mouse cursor when screenshot is taking (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: ScopedCursorHide to manage the hide/show Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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 "ui/snapshot/screenshot_grabber.h" 5 #include "ui/snapshot/screenshot_grabber.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 8
9 #include <climits> 9 #include <climits>
10 #include <string> 10 #include <string>
11 11
12 #include "base/bind.h" 12 #include "base/bind.h"
13 #include "base/callback.h" 13 #include "base/callback.h"
14 #include "base/files/file_util.h" 14 #include "base/files/file_util.h"
15 #include "base/location.h" 15 #include "base/location.h"
16 #include "base/logging.h" 16 #include "base/logging.h"
17 #include "base/message_loop/message_loop.h" 17 #include "base/message_loop/message_loop.h"
18 #include "base/single_thread_task_runner.h" 18 #include "base/single_thread_task_runner.h"
19 #include "base/task_runner.h" 19 #include "base/task_runner.h"
20 #include "base/threading/sequenced_worker_pool.h" 20 #include "base/threading/sequenced_worker_pool.h"
21 #include "base/threading/thread_task_runner_handle.h" 21 #include "base/threading/thread_task_runner_handle.h"
22 #include "base/time/time.h" 22 #include "base/time/time.h"
23 #include "ui/gfx/image/image.h" 23 #include "ui/gfx/image/image.h"
24 #include "ui/snapshot/snapshot.h" 24 #include "ui/snapshot/snapshot.h"
25 25
26 #if defined(USE_AURA) 26 #if defined(USE_AURA)
27 #include "ui/aura/client/cursor_client.h"
27 #include "ui/aura/window.h" 28 #include "ui/aura/window.h"
28 #endif 29 #endif
29 30
30 namespace ui { 31 namespace ui {
31 32
32 namespace { 33 namespace {
33 // The minimum interval between two screenshot commands. It has to be 34 // The minimum interval between two screenshot commands. It has to be
34 // more than 1000 to prevent the conflict of filenames. 35 // more than 1000 to prevent the conflict of filenames.
35 const int kScreenshotMinimumIntervalInMS = 1000; 36 const int kScreenshotMinimumIntervalInMS = 1000;
36 37
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
101 102
102 void ScreenshotGrabberDelegate::PrepareFileAndRunOnBlockingPool( 103 void ScreenshotGrabberDelegate::PrepareFileAndRunOnBlockingPool(
103 const base::FilePath& path, 104 const base::FilePath& path,
104 scoped_refptr<base::TaskRunner> blocking_task_runner, 105 scoped_refptr<base::TaskRunner> blocking_task_runner,
105 const FileCallback& callback_on_blocking_pool) { 106 const FileCallback& callback_on_blocking_pool) {
106 blocking_task_runner->PostTask( 107 blocking_task_runner->PostTask(
107 FROM_HERE, 108 FROM_HERE,
108 base::Bind(EnsureLocalDirectoryExists, path, callback_on_blocking_pool)); 109 base::Bind(EnsureLocalDirectoryExists, path, callback_on_blocking_pool));
109 } 110 }
110 111
112 #if defined(USE_AURA)
113 class ScreenshotGrabber::ScopedCursorHider {
114 public:
115 explicit ScopedCursorHider(aura::Window* window)
116 : window_(window), hid_cursor_(false) {
117 if (!window_->IsRootWindow())
sky 2016/07/22 16:14:44 This should be a DCHECK.
Qiang(Joe) Xu 2016/07/22 20:15:26 Done.
118 return;
119 aura::client::CursorClient* cursor_client =
sky 2016/07/22 16:14:44 Having to have all these checks in both the constr
Qiang(Joe) Xu 2016/07/22 20:15:26 done. Thanks for suggestion.
120 aura::client::GetCursorClient(window_);
121 if (!cursor_client)
122 return;
123 cursor_client->HideCursor();
124 hid_cursor_ = true;
125 }
126 ~ScopedCursorHider() {
127 if (!window_->IsRootWindow())
128 return;
129 if (hid_cursor_) {
130 aura::client::CursorClient* cursor_client =
131 aura::client::GetCursorClient(window_);
132 if (!cursor_client)
133 return;
134 cursor_client->ShowCursor();
135 }
136 }
137
138 private:
139 aura::Window* window_;
140 bool hid_cursor_;
141
142 DISALLOW_COPY_AND_ASSIGN(ScopedCursorHider);
143 };
144 #endif
145
111 ScreenshotGrabber::ScreenshotGrabber( 146 ScreenshotGrabber::ScreenshotGrabber(
112 ScreenshotGrabberDelegate* client, 147 ScreenshotGrabberDelegate* client,
113 scoped_refptr<base::TaskRunner> blocking_task_runner) 148 scoped_refptr<base::TaskRunner> blocking_task_runner)
114 : client_(client), 149 : client_(client),
115 blocking_task_runner_(blocking_task_runner), 150 blocking_task_runner_(blocking_task_runner),
116 factory_(this) { 151 factory_(this) {
117 } 152 }
118 153
119 ScreenshotGrabber::~ScreenshotGrabber() { 154 ScreenshotGrabber::~ScreenshotGrabber() {
120 } 155 }
121 156
122 void ScreenshotGrabber::TakeScreenshot(gfx::NativeWindow window, 157 void ScreenshotGrabber::TakeScreenshot(gfx::NativeWindow window,
123 const gfx::Rect& rect, 158 const gfx::Rect& rect,
124 const base::FilePath& screenshot_path) { 159 const base::FilePath& screenshot_path) {
125 DCHECK(base::MessageLoopForUI::IsCurrent()); 160 DCHECK(base::MessageLoopForUI::IsCurrent());
126 last_screenshot_timestamp_ = base::TimeTicks::Now(); 161 last_screenshot_timestamp_ = base::TimeTicks::Now();
127 162
128 bool is_partial = true; 163 bool is_partial = true;
129 // Window identifier is used to log a message on failure to capture a full 164 // Window identifier is used to log a message on failure to capture a full
130 // screen (i.e. non partial) screenshot. The only time is_partial can be 165 // screen (i.e. non partial) screenshot. The only time is_partial can be
131 // false, we will also have an identification string for the window. 166 // false, we will also have an identification string for the window.
132 std::string window_identifier; 167 std::string window_identifier;
133 #if defined(USE_AURA) 168 #if defined(USE_AURA)
134 aura::Window* aura_window = static_cast<aura::Window*>(window); 169 aura::Window* aura_window = static_cast<aura::Window*>(window);
135 is_partial = rect.size() != aura_window->bounds().size(); 170 is_partial = rect.size() != aura_window->bounds().size();
136 window_identifier = aura_window->GetBoundsInScreen().ToString(); 171 window_identifier = aura_window->GetBoundsInScreen().ToString();
172
173 cursor_hider_.reset(new ScopedCursorHider(aura_window->GetRootWindow()));
137 #endif 174 #endif
138 ui::GrabWindowSnapshotAsync( 175 ui::GrabWindowSnapshotAsync(
139 window, rect, blocking_task_runner_, 176 window, rect, blocking_task_runner_,
140 base::Bind(&ScreenshotGrabber::GrabWindowSnapshotAsyncCallback, 177 base::Bind(&ScreenshotGrabber::GrabWindowSnapshotAsyncCallback,
141 factory_.GetWeakPtr(), window_identifier, screenshot_path, 178 factory_.GetWeakPtr(), window_identifier, screenshot_path,
142 is_partial)); 179 is_partial));
143 } 180 }
144 181
145 bool ScreenshotGrabber::CanTakeScreenshot() { 182 bool ScreenshotGrabber::CanTakeScreenshot() {
146 return last_screenshot_timestamp_.is_null() || 183 return last_screenshot_timestamp_.is_null() ||
147 base::TimeTicks::Now() - last_screenshot_timestamp_ > 184 base::TimeTicks::Now() - last_screenshot_timestamp_ >
148 base::TimeDelta::FromMilliseconds(kScreenshotMinimumIntervalInMS); 185 base::TimeDelta::FromMilliseconds(kScreenshotMinimumIntervalInMS);
149 } 186 }
150 187
151 void ScreenshotGrabber::NotifyScreenshotCompleted( 188 void ScreenshotGrabber::NotifyScreenshotCompleted(
152 ScreenshotGrabberObserver::Result screenshot_result, 189 ScreenshotGrabberObserver::Result screenshot_result,
153 const base::FilePath& screenshot_path) { 190 const base::FilePath& screenshot_path) {
154 DCHECK(base::MessageLoopForUI::IsCurrent()); 191 DCHECK(base::MessageLoopForUI::IsCurrent());
192 #if defined(USE_AURA)
193 cursor_hider_.reset();
194 #endif
155 FOR_EACH_OBSERVER(ScreenshotGrabberObserver, observers_, 195 FOR_EACH_OBSERVER(ScreenshotGrabberObserver, observers_,
156 OnScreenshotCompleted(screenshot_result, screenshot_path)); 196 OnScreenshotCompleted(screenshot_result, screenshot_path));
157 } 197 }
158 198
159 void ScreenshotGrabber::AddObserver(ScreenshotGrabberObserver* observer) { 199 void ScreenshotGrabber::AddObserver(ScreenshotGrabberObserver* observer) {
160 observers_.AddObserver(observer); 200 observers_.AddObserver(observer);
161 } 201 }
162 202
163 void ScreenshotGrabber::RemoveObserver(ScreenshotGrabberObserver* observer) { 203 void ScreenshotGrabber::RemoveObserver(ScreenshotGrabberObserver* observer) {
164 observers_.RemoveObserver(observer); 204 observers_.RemoveObserver(observer);
(...skipping 28 matching lines...) Expand all
193 233
194 ShowNotificationCallback notification_callback(base::Bind( 234 ShowNotificationCallback notification_callback(base::Bind(
195 &ScreenshotGrabber::NotifyScreenshotCompleted, factory_.GetWeakPtr())); 235 &ScreenshotGrabber::NotifyScreenshotCompleted, factory_.GetWeakPtr()));
196 client_->PrepareFileAndRunOnBlockingPool( 236 client_->PrepareFileAndRunOnBlockingPool(
197 screenshot_path, blocking_task_runner_, 237 screenshot_path, blocking_task_runner_,
198 base::Bind(&SaveScreenshot, base::ThreadTaskRunnerHandle::Get(), 238 base::Bind(&SaveScreenshot, base::ThreadTaskRunnerHandle::Get(),
199 notification_callback, screenshot_path, png_data)); 239 notification_callback, screenshot_path, png_data));
200 } 240 }
201 241
202 } // namespace ui 242 } // namespace ui
OLDNEW
« ui/snapshot/screenshot_grabber.h ('K') | « ui/snapshot/screenshot_grabber.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698