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 "chrome/browser/ui/panels/panel_drag_gtk.h" | 5 #include "chrome/browser/ui/panels/panel_drag_gtk.h" |
6 | 6 |
7 #include <gdk/gdkkeysyms.h> | 7 #include <gdk/gdkkeysyms.h> |
8 | 8 |
9 #include "chrome/browser/ui/panels/panel.h" | 9 #include "chrome/browser/ui/panels/panel.h" |
10 #include "chrome/browser/ui/panels/panel_constants.h" | 10 #include "chrome/browser/ui/panels/panel_constants.h" |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
126 g_signal_connect(drag_widget_, "button-press-event", | 126 g_signal_connect(drag_widget_, "button-press-event", |
127 G_CALLBACK(OnButtonPressEventThunk), this); | 127 G_CALLBACK(OnButtonPressEventThunk), this); |
128 g_signal_connect(drag_widget_, "button-release-event", | 128 g_signal_connect(drag_widget_, "button-release-event", |
129 G_CALLBACK(OnButtonReleaseEventThunk), this); | 129 G_CALLBACK(OnButtonReleaseEventThunk), this); |
130 g_signal_connect(drag_widget_, "grab-broken-event", | 130 g_signal_connect(drag_widget_, "grab-broken-event", |
131 G_CALLBACK(OnGrabBrokenEventThunk), this); | 131 G_CALLBACK(OnGrabBrokenEventThunk), this); |
132 } | 132 } |
133 | 133 |
134 PanelDragGtk::~PanelDragGtk() { | 134 PanelDragGtk::~PanelDragGtk() { |
135 EndDrag(true); // Clean up drag state. | 135 EndDrag(true); // Clean up drag state. |
| 136 ReleasePointerAndKeyboardGrab(); |
136 } | 137 } |
137 | 138 |
138 void PanelDragGtk::AssertCleanState() { | 139 void PanelDragGtk::AssertCleanState() { |
139 DCHECK_EQ(NOT_DRAGGING, drag_state_); | 140 DCHECK_EQ(NOT_DRAGGING, drag_state_); |
140 DCHECK(!drag_delegate_); | 141 DCHECK(!drag_delegate_); |
141 DCHECK(!initial_mouse_down_); | 142 DCHECK(!initial_mouse_down_); |
142 DCHECK(!click_handler_); | 143 DCHECK(!click_handler_); |
143 } | 144 } |
144 | 145 |
145 void PanelDragGtk::InitialWindowEdgeMousePress(GdkEventButton* event, | 146 void PanelDragGtk::InitialWindowEdgeMousePress(GdkEventButton* event, |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
186 DLOG(ERROR) << "Unable to grab pointer or keyboard (pointer_status=" | 187 DLOG(ERROR) << "Unable to grab pointer or keyboard (pointer_status=" |
187 << pointer_grab_status << ", keyboard_status=" | 188 << pointer_grab_status << ", keyboard_status=" |
188 << keyboard_grab_status << ")"; | 189 << keyboard_grab_status << ")"; |
189 EndDrag(true); | 190 EndDrag(true); |
190 return; | 191 return; |
191 } | 192 } |
192 | 193 |
193 gtk_grab_add(drag_widget_); | 194 gtk_grab_add(drag_widget_); |
194 } | 195 } |
195 | 196 |
| 197 void PanelDragGtk::ReleasePointerAndKeyboardGrab() { |
| 198 if (drag_state_ == NOT_DRAGGING) |
| 199 return; |
| 200 |
| 201 DCHECK_EQ(DRAG_ENDED_WAITING_FOR_MOUSE_RELEASE, drag_state_); |
| 202 gdk_pointer_ungrab(GDK_CURRENT_TIME); |
| 203 gdk_keyboard_ungrab(GDK_CURRENT_TIME); |
| 204 gtk_grab_remove(drag_widget_); |
| 205 drag_state_ = NOT_DRAGGING; // Drag is truly over now. |
| 206 } |
| 207 |
196 void PanelDragGtk::EndDrag(bool canceled) { | 208 void PanelDragGtk::EndDrag(bool canceled) { |
197 if (initial_mouse_down_) { | 209 if (initial_mouse_down_) { |
198 gdk_event_free(initial_mouse_down_); | 210 gdk_event_free(initial_mouse_down_); |
199 initial_mouse_down_ = NULL; | 211 initial_mouse_down_ = NULL; |
200 } | 212 } |
201 | 213 |
202 if (drag_delegate_) { | 214 if (drag_delegate_) { |
203 gdk_pointer_ungrab(GDK_CURRENT_TIME); | |
204 gdk_keyboard_ungrab(GDK_CURRENT_TIME); | |
205 gtk_grab_remove(drag_widget_); | |
206 | |
207 if (drag_state_ == DRAG_IN_PROGRESS) { | 215 if (drag_state_ == DRAG_IN_PROGRESS) { |
208 drag_delegate_->DragEnded(canceled); | 216 drag_delegate_->DragEnded(canceled); |
209 drag_state_ = NOT_DRAGGING; | 217 drag_state_ = DRAG_ENDED_WAITING_FOR_MOUSE_RELEASE; |
210 } | 218 } |
211 | 219 |
212 delete drag_delegate_; | 220 delete drag_delegate_; |
213 drag_delegate_ = NULL; | 221 drag_delegate_ = NULL; |
214 } | 222 } |
215 | 223 |
216 click_handler_ = NULL; | 224 click_handler_ = NULL; |
217 } | 225 } |
218 | 226 |
219 gboolean PanelDragGtk::OnMouseMoveEvent(GtkWidget* widget, | 227 gboolean PanelDragGtk::OnMouseMoveEvent(GtkWidget* widget, |
220 GdkEventMotion* event) { | 228 GdkEventMotion* event) { |
221 DCHECK(drag_delegate_); | 229 DCHECK(drag_delegate_ || drag_state_ == DRAG_ENDED_WAITING_FOR_MOUSE_RELEASE); |
| 230 if (!drag_delegate_) |
| 231 return TRUE; |
222 | 232 |
223 gdouble new_x_double; | 233 gdouble new_x_double; |
224 gdouble new_y_double; | 234 gdouble new_y_double; |
225 gdk_event_get_root_coords(reinterpret_cast<GdkEvent*>(event), | 235 gdk_event_get_root_coords(reinterpret_cast<GdkEvent*>(event), |
226 &new_x_double, &new_y_double); | 236 &new_x_double, &new_y_double); |
227 gint new_x = static_cast<gint>(new_x_double); | 237 gint new_x = static_cast<gint>(new_x_double); |
228 gint new_y = static_cast<gint>(new_y_double); | 238 gint new_y = static_cast<gint>(new_y_double); |
229 | 239 |
230 // Begin dragging only after mouse has moved beyond the drag threshold. | 240 // Begin dragging only after mouse has moved beyond the drag threshold. |
231 if (drag_state_ == NOT_DRAGGING) { | 241 if (drag_state_ == NOT_DRAGGING) { |
(...skipping 15 matching lines...) Expand all Loading... |
247 } | 257 } |
248 | 258 |
249 if (drag_state_ == DRAG_IN_PROGRESS) | 259 if (drag_state_ == DRAG_IN_PROGRESS) |
250 drag_delegate_->Dragged(gfx::Point(new_x, new_y)); | 260 drag_delegate_->Dragged(gfx::Point(new_x, new_y)); |
251 | 261 |
252 return TRUE; | 262 return TRUE; |
253 } | 263 } |
254 | 264 |
255 gboolean PanelDragGtk::OnButtonPressEvent(GtkWidget* widget, | 265 gboolean PanelDragGtk::OnButtonPressEvent(GtkWidget* widget, |
256 GdkEventButton* event) { | 266 GdkEventButton* event) { |
257 DCHECK(drag_delegate_); | 267 DCHECK(drag_delegate_ || drag_state_ == DRAG_ENDED_WAITING_FOR_MOUSE_RELEASE); |
258 return TRUE; | 268 return TRUE; |
259 } | 269 } |
260 | 270 |
261 gboolean PanelDragGtk::OnButtonReleaseEvent(GtkWidget* widget, | 271 gboolean PanelDragGtk::OnButtonReleaseEvent(GtkWidget* widget, |
262 GdkEventButton* event) { | 272 GdkEventButton* event) { |
263 DCHECK(drag_delegate_); | 273 DCHECK(drag_delegate_ || drag_state_ == DRAG_ENDED_WAITING_FOR_MOUSE_RELEASE); |
264 | |
265 if (event->button == 1) { | 274 if (event->button == 1) { |
266 // Treat release as a mouse click if drag was never started. | 275 // There will be no drag delegate if drag was canceled/ended using |
267 if (drag_state_ == NOT_DRAGGING && click_handler_) { | 276 // the keyboard before the mouse was released. |
268 gtk_propagate_event(click_handler_, | 277 if (drag_delegate_) { |
269 reinterpret_cast<GdkEvent*>(event)); | 278 // Treat release as a mouse click if drag was never started. |
| 279 if (drag_state_ == NOT_DRAGGING && click_handler_) { |
| 280 gtk_propagate_event(click_handler_, |
| 281 reinterpret_cast<GdkEvent*>(event)); |
| 282 } |
| 283 // Cleanup state regardless. |
| 284 EndDrag(false); |
270 } | 285 } |
271 // Cleanup state regardless. | 286 ReleasePointerAndKeyboardGrab(); |
272 EndDrag(false); | |
273 } | 287 } |
274 | 288 |
275 return TRUE; | 289 return TRUE; |
276 } | 290 } |
277 | 291 |
278 gboolean PanelDragGtk::OnKeyPressEvent(GtkWidget* widget, | 292 gboolean PanelDragGtk::OnKeyPressEvent(GtkWidget* widget, |
279 GdkEventKey* event) { | 293 GdkEventKey* event) { |
280 DCHECK(drag_delegate_); | 294 DCHECK(drag_delegate_ || drag_state_ == DRAG_ENDED_WAITING_FOR_MOUSE_RELEASE); |
281 return TRUE; | 295 return TRUE; |
282 } | 296 } |
283 | 297 |
284 gboolean PanelDragGtk::OnKeyReleaseEvent(GtkWidget* widget, | 298 gboolean PanelDragGtk::OnKeyReleaseEvent(GtkWidget* widget, |
285 GdkEventKey* event) { | 299 GdkEventKey* event) { |
286 DCHECK(drag_delegate_); | 300 DCHECK(drag_delegate_ || drag_state_ == DRAG_ENDED_WAITING_FOR_MOUSE_RELEASE); |
| 301 if (!drag_delegate_) |
| 302 return TRUE; |
287 | 303 |
288 switch (event->keyval) { | 304 switch (event->keyval) { |
289 case GDK_Escape: | 305 case GDK_Escape: |
290 EndDrag(true); // Cancel drag. | 306 EndDrag(true); // Cancel drag. |
291 break; | 307 break; |
292 case GDK_Return: | 308 case GDK_Return: |
293 case GDK_KP_Enter: | 309 case GDK_KP_Enter: |
294 case GDK_ISO_Enter: | 310 case GDK_ISO_Enter: |
295 case GDK_space: | 311 case GDK_space: |
296 EndDrag(false); // Normal end. | 312 EndDrag(false); // Normal end. |
297 break; | 313 break; |
298 } | 314 } |
299 return TRUE; | 315 return TRUE; |
300 } | 316 } |
301 | 317 |
302 gboolean PanelDragGtk::OnGrabBrokenEvent(GtkWidget* widget, | 318 gboolean PanelDragGtk::OnGrabBrokenEvent(GtkWidget* widget, |
303 GdkEventGrabBroken* event) { | 319 GdkEventGrabBroken* event) { |
304 DCHECK(drag_delegate_); | 320 DCHECK(drag_delegate_ || drag_state_ == DRAG_ENDED_WAITING_FOR_MOUSE_RELEASE); |
305 EndDrag(true); // Cancel drag. | 321 EndDrag(true); // Cancel drag. |
| 322 ReleasePointerAndKeyboardGrab(); |
306 return TRUE; | 323 return TRUE; |
307 } | 324 } |
OLD | NEW |