OLD | NEW |
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_desktop_window_move_client.h" | 5 #include "ui/views/widget/desktop_aura/x11_desktop_window_move_client.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. | 8 // Get rid of a macro from Xlib.h that conflicts with Aura's RootWindow class. |
9 #undef RootWindow | 9 #undef RootWindow |
10 | 10 |
11 #include "base/debug/stack_trace.h" | 11 #include "base/debug/stack_trace.h" |
12 #include "base/message_loop/message_loop.h" | 12 #include "base/message_loop/message_loop.h" |
13 #include "base/message_loop/message_pump_x11.h" | 13 #include "base/message_loop/message_pump_x11.h" |
14 #include "base/run_loop.h" | 14 #include "base/run_loop.h" |
15 #include "ui/aura/env.h" | 15 #include "ui/aura/env.h" |
16 #include "ui/aura/root_window.h" | 16 #include "ui/aura/root_window.h" |
17 #include "ui/base/x/x11_util.h" | 17 #include "ui/base/x/x11_util.h" |
18 #include "ui/events/event.h" | 18 #include "ui/events/event.h" |
19 #include "ui/gfx/screen.h" | 19 #include "ui/gfx/screen.h" |
20 | 20 |
| 21 namespace { |
| 22 |
| 23 // Delay moving the window. |
| 24 // |
| 25 // When we receive a mouse move event, we have to have it processed in a |
| 26 // different run through the message pump because moving the window will |
| 27 // otherwise prevent tasks from running. |
| 28 // |
| 29 // This constant was derived with playing with builds of chrome; it has no |
| 30 // theoretical justification. |
| 31 // |
| 32 // TODO(erg): This helps with the performance of dragging windows, but it |
| 33 // doesn't really solve the hard problems, which is that various calls to X11, |
| 34 // such as XQueryPointer, ui::IsWindowVisible() and ui::WindowContainsPoint() |
| 35 // take a while to get replies and block in the process. I've seen all of the |
| 36 // above take as long as 20ms to respond. |
| 37 const int kMoveDelay = 3; |
| 38 |
| 39 } // namespace |
| 40 |
21 namespace views { | 41 namespace views { |
22 | 42 |
23 X11DesktopWindowMoveClient::X11DesktopWindowMoveClient() | 43 X11DesktopWindowMoveClient::X11DesktopWindowMoveClient() |
24 : move_loop_(this), | 44 : move_loop_(this), |
25 root_window_(NULL) { | 45 root_window_(NULL) { |
26 } | 46 } |
27 | 47 |
28 X11DesktopWindowMoveClient::~X11DesktopWindowMoveClient() {} | 48 X11DesktopWindowMoveClient::~X11DesktopWindowMoveClient() {} |
29 | 49 |
30 void X11DesktopWindowMoveClient::OnMouseMovement(XMotionEvent* event) { | 50 void X11DesktopWindowMoveClient::OnMouseMovement(XMotionEvent* event) { |
31 gfx::Point cursor_point(event->x_root, event->y_root); | 51 gfx::Point cursor_point(event->x_root, event->y_root); |
32 gfx::Point system_loc = cursor_point - window_offset_; | 52 gfx::Point system_loc = cursor_point - window_offset_; |
33 root_window_->SetHostBounds(gfx::Rect( | 53 |
34 system_loc, root_window_->GetHostSize())); | 54 gfx::Rect target_rect(system_loc, root_window_->GetHostSize()); |
| 55 |
| 56 window_move_timer_.Start( |
| 57 FROM_HERE, |
| 58 base::TimeDelta::FromMilliseconds(kMoveDelay), |
| 59 base::Bind(&X11DesktopWindowMoveClient::SetHostBounds, |
| 60 base::Unretained(this), |
| 61 target_rect)); |
35 } | 62 } |
36 | 63 |
37 void X11DesktopWindowMoveClient::OnMouseReleased() { | 64 void X11DesktopWindowMoveClient::OnMouseReleased() { |
38 EndMoveLoop(); | 65 EndMoveLoop(); |
39 } | 66 } |
40 | 67 |
41 void X11DesktopWindowMoveClient::OnMoveLoopEnded() { | 68 void X11DesktopWindowMoveClient::OnMoveLoopEnded() { |
42 root_window_ = NULL; | 69 root_window_ = NULL; |
43 } | 70 } |
44 | 71 |
45 //////////////////////////////////////////////////////////////////////////////// | 72 //////////////////////////////////////////////////////////////////////////////// |
46 // DesktopRootWindowHostLinux, aura::client::WindowMoveClient implementation: | 73 // DesktopRootWindowHostLinux, aura::client::WindowMoveClient implementation: |
47 | 74 |
48 aura::client::WindowMoveResult X11DesktopWindowMoveClient::RunMoveLoop( | 75 aura::client::WindowMoveResult X11DesktopWindowMoveClient::RunMoveLoop( |
49 aura::Window* source, | 76 aura::Window* source, |
50 const gfx::Vector2d& drag_offset, | 77 const gfx::Vector2d& drag_offset, |
51 aura::client::WindowMoveSource move_source) { | 78 aura::client::WindowMoveSource move_source) { |
52 window_offset_ = drag_offset; | 79 window_offset_ = drag_offset; |
53 root_window_ = source->GetDispatcher(); | 80 root_window_ = source->GetDispatcher(); |
54 | 81 |
55 bool success = move_loop_.RunMoveLoop(source, root_window_->last_cursor()); | 82 bool success = move_loop_.RunMoveLoop(source, root_window_->last_cursor()); |
56 return success ? aura::client::MOVE_SUCCESSFUL : aura::client::MOVE_CANCELED; | 83 return success ? aura::client::MOVE_SUCCESSFUL : aura::client::MOVE_CANCELED; |
57 } | 84 } |
58 | 85 |
59 void X11DesktopWindowMoveClient::EndMoveLoop() { | 86 void X11DesktopWindowMoveClient::EndMoveLoop() { |
| 87 window_move_timer_.Stop(); |
60 move_loop_.EndMoveLoop(); | 88 move_loop_.EndMoveLoop(); |
61 } | 89 } |
62 | 90 |
| 91 //////////////////////////////////////////////////////////////////////////////// |
| 92 // DesktopRootWindowHostLinux, private: |
| 93 |
| 94 void X11DesktopWindowMoveClient::SetHostBounds(const gfx::Rect& rect) { |
| 95 root_window_->SetHostBounds(rect); |
| 96 } |
| 97 |
63 } // namespace views | 98 } // namespace views |
OLD | NEW |