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_whole_screen_move_loop.h" | 5 #include "ui/views/widget/desktop_aura/x11_whole_screen_move_loop.h" |
6 | 6 |
7 #include <X11/keysym.h> | 7 #include <X11/keysym.h> |
8 #include <X11/Xlib.h> | 8 #include <X11/Xlib.h> |
9 | 9 |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
43 should_reset_mouse_flags_(false), | 43 should_reset_mouse_flags_(false), |
44 grab_input_window_(None), | 44 grab_input_window_(None), |
45 grabbed_pointer_(false), | 45 grabbed_pointer_(false), |
46 canceled_(false), | 46 canceled_(false), |
47 weak_factory_(this) { | 47 weak_factory_(this) { |
48 } | 48 } |
49 | 49 |
50 X11WholeScreenMoveLoop::~X11WholeScreenMoveLoop() {} | 50 X11WholeScreenMoveLoop::~X11WholeScreenMoveLoop() {} |
51 | 51 |
52 void X11WholeScreenMoveLoop::DispatchMouseMovement() { | 52 void X11WholeScreenMoveLoop::DispatchMouseMovement() { |
53 if (!weak_factory_.HasWeakPtrs()) | 53 if (!last_motion_in_screen_) |
54 return; | 54 return; |
55 weak_factory_.InvalidateWeakPtrs(); | |
56 delegate_->OnMouseMovement(last_motion_in_screen_->location(), | 55 delegate_->OnMouseMovement(last_motion_in_screen_->location(), |
57 last_motion_in_screen_->flags(), | 56 last_motion_in_screen_->flags(), |
58 last_motion_in_screen_->time_stamp()); | 57 last_motion_in_screen_->time_stamp()); |
59 last_motion_in_screen_.reset(); | 58 last_motion_in_screen_.reset(); |
60 } | 59 } |
61 | 60 |
62 //////////////////////////////////////////////////////////////////////////////// | 61 //////////////////////////////////////////////////////////////////////////////// |
63 // DesktopWindowTreeHostLinux, ui::PlatformEventDispatcher implementation: | 62 // DesktopWindowTreeHostLinux, ui::PlatformEventDispatcher implementation: |
64 | 63 |
65 bool X11WholeScreenMoveLoop::CanDispatchEvent(const ui::PlatformEvent& event) { | 64 bool X11WholeScreenMoveLoop::CanDispatchEvent(const ui::PlatformEvent& event) { |
66 return in_move_loop_; | 65 return in_move_loop_; |
67 } | 66 } |
68 | 67 |
69 uint32_t X11WholeScreenMoveLoop::DispatchEvent(const ui::PlatformEvent& event) { | 68 uint32_t X11WholeScreenMoveLoop::DispatchEvent(const ui::PlatformEvent& event) { |
70 // This method processes all events while the move loop is active. | 69 // This method processes all events while the move loop is active. |
71 if (!in_move_loop_) | 70 if (!in_move_loop_) |
72 return ui::POST_DISPATCH_PERFORM_DEFAULT; | 71 return ui::POST_DISPATCH_PERFORM_DEFAULT; |
73 | 72 |
74 XEvent* xev = event; | 73 XEvent* xev = event; |
75 ui::EventType type = ui::EventTypeFromNative(xev); | 74 ui::EventType type = ui::EventTypeFromNative(xev); |
76 switch (type) { | 75 switch (type) { |
77 case ui::ET_MOUSE_MOVED: | 76 case ui::ET_MOUSE_MOVED: |
78 case ui::ET_MOUSE_DRAGGED: | 77 case ui::ET_MOUSE_DRAGGED: { |
| 78 bool dispatch_mouse_event = !last_motion_in_screen_.get(); |
79 last_motion_in_screen_.reset( | 79 last_motion_in_screen_.reset( |
80 static_cast<ui::MouseEvent*>(ui::EventFromNative(xev).release())); | 80 static_cast<ui::MouseEvent*>(ui::EventFromNative(xev).release())); |
81 last_motion_in_screen_->set_location( | 81 last_motion_in_screen_->set_location( |
82 ui::EventSystemLocationFromNative(xev)); | 82 ui::EventSystemLocationFromNative(xev)); |
83 if (!weak_factory_.HasWeakPtrs()) { | 83 if (dispatch_mouse_event) { |
84 // Post a task to dispatch mouse movement event when control returns to | 84 // Post a task to dispatch mouse movement event when control returns to |
85 // the message loop. This allows smoother dragging since the events are | 85 // the message loop. This allows smoother dragging since the events are |
86 // dispatched without waiting for the drag widget updates. | 86 // dispatched without waiting for the drag widget updates. |
87 base::MessageLoopForUI::current()->PostTask( | 87 base::MessageLoopForUI::current()->PostTask( |
88 FROM_HERE, | 88 FROM_HERE, |
89 base::Bind(&X11WholeScreenMoveLoop::DispatchMouseMovement, | 89 base::Bind(&X11WholeScreenMoveLoop::DispatchMouseMovement, |
90 weak_factory_.GetWeakPtr())); | 90 weak_factory_.GetWeakPtr())); |
91 } | 91 } |
92 return ui::POST_DISPATCH_NONE; | 92 return ui::POST_DISPATCH_NONE; |
| 93 } |
93 case ui::ET_MOUSE_RELEASED: { | 94 case ui::ET_MOUSE_RELEASED: { |
94 int button = (xev->type == ButtonRelease) | 95 int button = (xev->type == ButtonRelease) |
95 ? xev->xbutton.button | 96 ? xev->xbutton.button |
96 : ui::EventButtonFromNative(xev); | 97 : ui::EventButtonFromNative(xev); |
97 if (button == Button1) { | 98 if (button == Button1) { |
98 // Assume that drags are being done with the left mouse button. Only | 99 // Assume that drags are being done with the left mouse button. Only |
99 // break the drag if the left mouse button was released. | 100 // break the drag if the left mouse button was released. |
100 DispatchMouseMovement(); | 101 DispatchMouseMovement(); |
101 delegate_->OnMouseReleased(); | 102 delegate_->OnMouseReleased(); |
102 | 103 |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
160 | 161 |
161 // We are handling a mouse drag outside of the aura::Window system. We must | 162 // We are handling a mouse drag outside of the aura::Window system. We must |
162 // manually make aura think that the mouse button is pressed so that we don't | 163 // manually make aura think that the mouse button is pressed so that we don't |
163 // draw extraneous tooltips. | 164 // draw extraneous tooltips. |
164 aura::Env* env = aura::Env::GetInstance(); | 165 aura::Env* env = aura::Env::GetInstance(); |
165 if (!env->IsMouseButtonDown()) { | 166 if (!env->IsMouseButtonDown()) { |
166 env->set_mouse_button_flags(ui::EF_LEFT_MOUSE_BUTTON); | 167 env->set_mouse_button_flags(ui::EF_LEFT_MOUSE_BUTTON); |
167 should_reset_mouse_flags_ = true; | 168 should_reset_mouse_flags_ = true; |
168 } | 169 } |
169 | 170 |
| 171 base::WeakPtr<X11WholeScreenMoveLoop> alive(weak_factory_.GetWeakPtr()); |
| 172 |
170 in_move_loop_ = true; | 173 in_move_loop_ = true; |
171 canceled_ = false; | 174 canceled_ = false; |
172 base::MessageLoopForUI* loop = base::MessageLoopForUI::current(); | 175 base::MessageLoopForUI* loop = base::MessageLoopForUI::current(); |
173 base::MessageLoop::ScopedNestableTaskAllower allow_nested(loop); | 176 base::MessageLoop::ScopedNestableTaskAllower allow_nested(loop); |
174 base::RunLoop run_loop; | 177 base::RunLoop run_loop; |
175 quit_closure_ = run_loop.QuitClosure(); | 178 quit_closure_ = run_loop.QuitClosure(); |
176 run_loop.Run(); | 179 run_loop.Run(); |
| 180 |
| 181 if (!alive) |
| 182 return false; |
| 183 |
177 nested_dispatcher_ = old_dispatcher.Pass(); | 184 nested_dispatcher_ = old_dispatcher.Pass(); |
178 return !canceled_; | 185 return !canceled_; |
179 } | 186 } |
180 | 187 |
181 void X11WholeScreenMoveLoop::UpdateCursor(gfx::NativeCursor cursor) { | 188 void X11WholeScreenMoveLoop::UpdateCursor(gfx::NativeCursor cursor) { |
182 if (in_move_loop_) { | 189 if (in_move_loop_) { |
183 // We cannot call GrabPointer() because we do not want to change the | 190 // We cannot call GrabPointer() because we do not want to change the |
184 // "owner_events" property of the active pointer grab. | 191 // "owner_events" property of the active pointer grab. |
185 XChangeActivePointerGrab( | 192 XChangeActivePointerGrab( |
186 gfx::GetXDisplay(), | 193 gfx::GetXDisplay(), |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
275 DefaultRootWindow(display), | 282 DefaultRootWindow(display), |
276 -100, -100, 10, 10, | 283 -100, -100, 10, 10, |
277 0, CopyFromParent, InputOnly, CopyFromParent, | 284 0, CopyFromParent, InputOnly, CopyFromParent, |
278 attribute_mask, &swa); | 285 attribute_mask, &swa); |
279 XMapRaised(display, window); | 286 XMapRaised(display, window); |
280 ui::X11EventSource::GetInstance()->BlockUntilWindowMapped(window); | 287 ui::X11EventSource::GetInstance()->BlockUntilWindowMapped(window); |
281 return window; | 288 return window; |
282 } | 289 } |
283 | 290 |
284 } // namespace views | 291 } // namespace views |
OLD | NEW |