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

Side by Side Diff: ui/views/widget/desktop_aura/x11_whole_screen_move_loop.cc

Issue 452413002: [Refactor]: Move drag_widget_ out of X11WholeScreenMoveLoop (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 4 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 | Annotate | Revision Log
« no previous file with comments | « ui/views/widget/desktop_aura/x11_whole_screen_move_loop.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 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/views/widget/desktop_aura/x11_whole_screen_move_loop.h" 5 #include "ui/views/widget/desktop_aura/x11_whole_screen_move_loop.h"
6 6
7 #include <X11/Xlib.h> 7 #include <X11/Xlib.h>
8 // Get rid of a macro from Xlib.h that conflicts with Aura's RootWindow class.
9 #undef RootWindow
10 8
11 #include "base/bind.h" 9 #include "base/bind.h"
12 #include "base/message_loop/message_loop.h" 10 #include "base/message_loop/message_loop.h"
13 #include "base/run_loop.h" 11 #include "base/run_loop.h"
14 #include "third_party/skia/include/core/SkBitmap.h"
15 #include "ui/aura/env.h" 12 #include "ui/aura/env.h"
16 #include "ui/aura/window.h" 13 #include "ui/aura/window.h"
17 #include "ui/aura/window_event_dispatcher.h" 14 #include "ui/aura/window_event_dispatcher.h"
18 #include "ui/aura/window_tree_host.h" 15 #include "ui/aura/window_tree_host.h"
19 #include "ui/base/x/x11_util.h" 16 #include "ui/base/x/x11_util.h"
20 #include "ui/events/event.h" 17 #include "ui/events/event.h"
21 #include "ui/events/event_utils.h" 18 #include "ui/events/event_utils.h"
22 #include "ui/events/keycodes/keyboard_code_conversion_x.h" 19 #include "ui/events/keycodes/keyboard_code_conversion_x.h"
23 #include "ui/events/platform/scoped_event_dispatcher.h" 20 #include "ui/events/platform/scoped_event_dispatcher.h"
24 #include "ui/events/platform/x11/x11_event_source.h" 21 #include "ui/events/platform/x11/x11_event_source.h"
25 #include "ui/gfx/point_conversions.h" 22 #include "ui/gfx/point_conversions.h"
26 #include "ui/gfx/screen.h"
27 #include "ui/views/controls/image_view.h"
28 #include "ui/views/widget/widget.h"
29 23
30 namespace views { 24 namespace views {
31 25
32 namespace { 26 namespace {
33 27
34 // The minimum alpha before we declare a pixel transparent when searching in
35 // our source image.
36 const uint32 kMinAlpha = 32;
37 const unsigned char kDragWidgetOpacity = 0xc0;
38
39 class ScopedCapturer { 28 class ScopedCapturer {
40 public: 29 public:
41 explicit ScopedCapturer(aura::WindowTreeHost* host) 30 explicit ScopedCapturer(aura::WindowTreeHost* host)
42 : host_(host) { 31 : host_(host) {
43 host_->SetCapture(); 32 host_->SetCapture();
44 } 33 }
45 34
46 ~ScopedCapturer() { 35 ~ScopedCapturer() {
47 host_->ReleaseCapture(); 36 host_->ReleaseCapture();
48 } 37 }
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
93 // event that should have stopped the drag even if that mouse release happened 82 // event that should have stopped the drag even if that mouse release happened
94 // before the grab was granted. 83 // before the grab was granted.
95 if (!in_move_loop_) 84 if (!in_move_loop_)
96 return ui::POST_DISPATCH_PERFORM_DEFAULT; 85 return ui::POST_DISPATCH_PERFORM_DEFAULT;
97 XEvent* xev = event; 86 XEvent* xev = event;
98 87
99 // Note: the escape key is handled in the tab drag controller, which has 88 // Note: the escape key is handled in the tab drag controller, which has
100 // keyboard focus even though we took pointer grab. 89 // keyboard focus even though we took pointer grab.
101 switch (xev->type) { 90 switch (xev->type) {
102 case MotionNotify: { 91 case MotionNotify: {
103 if (drag_widget_.get()) {
104 gfx::Screen* screen = gfx::Screen::GetNativeScreen();
105 gfx::Point location = gfx::ToFlooredPoint(
106 screen->GetCursorScreenPoint() - drag_offset_);
107 drag_widget_->SetBounds(gfx::Rect(location, drag_image_.size()));
108 drag_widget_->StackAtTop();
109 }
110 last_xmotion_ = xev->xmotion; 92 last_xmotion_ = xev->xmotion;
111 if (!weak_factory_.HasWeakPtrs()) { 93 if (!weak_factory_.HasWeakPtrs()) {
112 // Post a task to dispatch mouse movement event when control returns to 94 // Post a task to dispatch mouse movement event when control returns to
113 // the message loop. This allows smoother dragging since the events are 95 // the message loop. This allows smoother dragging since the events are
114 // dispatched without waiting for the drag widget updates. 96 // dispatched without waiting for the drag widget updates.
115 base::MessageLoopForUI::current()->PostTask( 97 base::MessageLoopForUI::current()->PostTask(
116 FROM_HERE, 98 FROM_HERE,
117 base::Bind(&X11WholeScreenMoveLoop::DispatchMouseMovement, 99 base::Bind(&X11WholeScreenMoveLoop::DispatchMouseMovement,
118 weak_factory_.GetWeakPtr())); 100 weak_factory_.GetWeakPtr()));
119 } 101 }
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
199 // ScopedCapturer to avoid possibility of logically keeping multiple grabs. 181 // ScopedCapturer to avoid possibility of logically keeping multiple grabs.
200 if (!GrabPointerAndKeyboard(cursor)) { 182 if (!GrabPointerAndKeyboard(cursor)) {
201 XDestroyWindow(gfx::GetXDisplay(), grab_input_window_); 183 XDestroyWindow(gfx::GetXDisplay(), grab_input_window_);
202 return false; 184 return false;
203 } 185 }
204 186
205 scoped_ptr<ui::ScopedEventDispatcher> old_dispatcher = 187 scoped_ptr<ui::ScopedEventDispatcher> old_dispatcher =
206 nested_dispatcher_.Pass(); 188 nested_dispatcher_.Pass();
207 nested_dispatcher_ = 189 nested_dispatcher_ =
208 ui::PlatformEventSource::GetInstance()->OverrideDispatcher(this); 190 ui::PlatformEventSource::GetInstance()->OverrideDispatcher(this);
209 if (!drag_image_.isNull() && CheckIfIconValid())
210 CreateDragImageWindow();
211 191
212 // We are handling a mouse drag outside of the aura::RootWindow system. We 192 // We are handling a mouse drag outside of the aura::RootWindow system. We
213 // must manually make aura think that the mouse button is pressed so that we 193 // must manually make aura think that the mouse button is pressed so that we
214 // don't draw extraneous tooltips. 194 // don't draw extraneous tooltips.
215 aura::Env* env = aura::Env::GetInstance(); 195 aura::Env* env = aura::Env::GetInstance();
216 if (!env->IsMouseButtonDown()) { 196 if (!env->IsMouseButtonDown()) {
217 env->set_mouse_button_flags(ui::EF_LEFT_MOUSE_BUTTON); 197 env->set_mouse_button_flags(ui::EF_LEFT_MOUSE_BUTTON);
218 should_reset_mouse_flags_ = true; 198 should_reset_mouse_flags_ = true;
219 } 199 }
220 200
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
259 // Ungrab before we let go of the window. 239 // Ungrab before we let go of the window.
260 XDisplay* display = gfx::GetXDisplay(); 240 XDisplay* display = gfx::GetXDisplay();
261 // Only ungrab pointer if capture was not switched to another window. 241 // Only ungrab pointer if capture was not switched to another window.
262 if (has_grab_) { 242 if (has_grab_) {
263 XUngrabPointer(display, CurrentTime); 243 XUngrabPointer(display, CurrentTime);
264 XUngrabKeyboard(display, CurrentTime); 244 XUngrabKeyboard(display, CurrentTime);
265 } 245 }
266 246
267 // Restore the previous dispatcher. 247 // Restore the previous dispatcher.
268 nested_dispatcher_.reset(); 248 nested_dispatcher_.reset();
269 drag_widget_.reset();
270 delegate_->OnMoveLoopEnded(); 249 delegate_->OnMoveLoopEnded();
271 XDestroyWindow(display, grab_input_window_); 250 XDestroyWindow(display, grab_input_window_);
272 grab_input_window_ = None; 251 grab_input_window_ = None;
273 252
274 in_move_loop_ = false; 253 in_move_loop_ = false;
275 quit_closure_.Run(); 254 quit_closure_.Run();
276 } 255 }
277 256
278 void X11WholeScreenMoveLoop::SetDragImage(const gfx::ImageSkia& image,
279 const gfx::Vector2dF& offset) {
280 drag_image_ = image;
281 drag_offset_ = offset;
282 }
283
284 bool X11WholeScreenMoveLoop::GrabPointerAndKeyboard(gfx::NativeCursor cursor) { 257 bool X11WholeScreenMoveLoop::GrabPointerAndKeyboard(gfx::NativeCursor cursor) {
285 XDisplay* display = gfx::GetXDisplay(); 258 XDisplay* display = gfx::GetXDisplay();
286 XGrabServer(display); 259 XGrabServer(display);
287 260
288 XUngrabPointer(display, CurrentTime); 261 XUngrabPointer(display, CurrentTime);
289 int ret = XGrabPointer( 262 int ret = XGrabPointer(
290 display, 263 display,
291 grab_input_window_, 264 grab_input_window_,
292 False, 265 False,
293 ButtonPressMask | ButtonReleaseMask | PointerMotionMask, 266 ButtonPressMask | ButtonReleaseMask | PointerMotionMask,
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
335 Window window = XCreateWindow(display, 308 Window window = XCreateWindow(display,
336 DefaultRootWindow(display), 309 DefaultRootWindow(display),
337 -100, -100, 10, 10, 310 -100, -100, 10, 10,
338 0, CopyFromParent, InputOnly, CopyFromParent, 311 0, CopyFromParent, InputOnly, CopyFromParent,
339 attribute_mask, &swa); 312 attribute_mask, &swa);
340 XMapRaised(display, window); 313 XMapRaised(display, window);
341 ui::X11EventSource::GetInstance()->BlockUntilWindowMapped(window); 314 ui::X11EventSource::GetInstance()->BlockUntilWindowMapped(window);
342 return window; 315 return window;
343 } 316 }
344 317
345 void X11WholeScreenMoveLoop::CreateDragImageWindow() {
346 Widget* widget = new Widget;
347 Widget::InitParams params(Widget::InitParams::TYPE_DRAG);
348 params.opacity = Widget::InitParams::OPAQUE_WINDOW;
349 params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
350 params.accept_events = false;
351
352 gfx::Point location = gfx::ToFlooredPoint(
353 gfx::Screen::GetNativeScreen()->GetCursorScreenPoint() - drag_offset_);
354 params.bounds = gfx::Rect(location, drag_image_.size());
355 widget->set_focus_on_creation(false);
356 widget->set_frame_type(Widget::FRAME_TYPE_FORCE_NATIVE);
357 widget->Init(params);
358 widget->SetOpacity(kDragWidgetOpacity);
359 widget->GetNativeWindow()->SetName("DragWindow");
360
361 ImageView* image = new ImageView();
362 image->SetImage(drag_image_);
363 image->SetBounds(0, 0, drag_image_.width(), drag_image_.height());
364 widget->SetContentsView(image);
365 widget->Show();
366 widget->GetNativeWindow()->layer()->SetFillsBoundsOpaquely(false);
367
368 drag_widget_.reset(widget);
369 }
370
371 bool X11WholeScreenMoveLoop::CheckIfIconValid() {
372 // Because we need a GL context per window, we do a quick check so that we
373 // don't make another context if the window would just be displaying a mostly
374 // transparent image.
375 const SkBitmap* in_bitmap = drag_image_.bitmap();
376 SkAutoLockPixels in_lock(*in_bitmap);
377 for (int y = 0; y < in_bitmap->height(); ++y) {
378 uint32* in_row = in_bitmap->getAddr32(0, y);
379
380 for (int x = 0; x < in_bitmap->width(); ++x) {
381 if (SkColorGetA(in_row[x]) > kMinAlpha)
382 return true;
383 }
384 }
385
386 return false;
387 }
388
389 } // namespace views 318 } // namespace views
OLDNEW
« no previous file with comments | « ui/views/widget/desktop_aura/x11_whole_screen_move_loop.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698