Chromium Code Reviews| 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() { | |
|
Dmitry Titov
2012/04/27 22:28:32
This function can be called twice it seems. If we
jennb
2012/04/27 22:52:06
Done.
| |
| 198 DCHECK_NE(DRAG_IN_PROGRESS, drag_state_); | |
| 199 gdk_pointer_ungrab(GDK_CURRENT_TIME); | |
| 200 gdk_keyboard_ungrab(GDK_CURRENT_TIME); | |
| 201 gtk_grab_remove(drag_widget_); | |
| 202 drag_state_ = NOT_DRAGGING; // Drag is truly over now. | |
| 203 } | |
| 204 | |
| 196 void PanelDragGtk::EndDrag(bool canceled) { | 205 void PanelDragGtk::EndDrag(bool canceled) { |
| 197 if (initial_mouse_down_) { | 206 if (initial_mouse_down_) { |
| 198 gdk_event_free(initial_mouse_down_); | 207 gdk_event_free(initial_mouse_down_); |
| 199 initial_mouse_down_ = NULL; | 208 initial_mouse_down_ = NULL; |
| 200 } | 209 } |
| 201 | 210 |
| 202 if (drag_delegate_) { | 211 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) { | 212 if (drag_state_ == DRAG_IN_PROGRESS) { |
| 208 drag_delegate_->DragEnded(canceled); | 213 drag_delegate_->DragEnded(canceled); |
| 209 drag_state_ = NOT_DRAGGING; | 214 drag_state_ = DRAG_ENDED_WAITING_FOR_MOUSE_RELEASE; |
| 210 } | 215 } |
| 211 | 216 |
| 212 delete drag_delegate_; | 217 delete drag_delegate_; |
| 213 drag_delegate_ = NULL; | 218 drag_delegate_ = NULL; |
| 214 } | 219 } |
| 215 | 220 |
| 216 click_handler_ = NULL; | 221 click_handler_ = NULL; |
| 217 } | 222 } |
| 218 | 223 |
| 219 gboolean PanelDragGtk::OnMouseMoveEvent(GtkWidget* widget, | 224 gboolean PanelDragGtk::OnMouseMoveEvent(GtkWidget* widget, |
| 220 GdkEventMotion* event) { | 225 GdkEventMotion* event) { |
| 221 DCHECK(drag_delegate_); | 226 DCHECK(drag_delegate_ || drag_state_ == DRAG_ENDED_WAITING_FOR_MOUSE_RELEASE); |
| 227 if (!drag_delegate_) | |
| 228 return TRUE; | |
| 222 | 229 |
| 223 gdouble new_x_double; | 230 gdouble new_x_double; |
| 224 gdouble new_y_double; | 231 gdouble new_y_double; |
| 225 gdk_event_get_root_coords(reinterpret_cast<GdkEvent*>(event), | 232 gdk_event_get_root_coords(reinterpret_cast<GdkEvent*>(event), |
| 226 &new_x_double, &new_y_double); | 233 &new_x_double, &new_y_double); |
| 227 gint new_x = static_cast<gint>(new_x_double); | 234 gint new_x = static_cast<gint>(new_x_double); |
| 228 gint new_y = static_cast<gint>(new_y_double); | 235 gint new_y = static_cast<gint>(new_y_double); |
| 229 | 236 |
| 230 // Begin dragging only after mouse has moved beyond the drag threshold. | 237 // Begin dragging only after mouse has moved beyond the drag threshold. |
| 231 if (drag_state_ == NOT_DRAGGING) { | 238 if (drag_state_ == NOT_DRAGGING) { |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 247 } | 254 } |
| 248 | 255 |
| 249 if (drag_state_ == DRAG_IN_PROGRESS) | 256 if (drag_state_ == DRAG_IN_PROGRESS) |
| 250 drag_delegate_->Dragged(gfx::Point(new_x, new_y)); | 257 drag_delegate_->Dragged(gfx::Point(new_x, new_y)); |
| 251 | 258 |
| 252 return TRUE; | 259 return TRUE; |
| 253 } | 260 } |
| 254 | 261 |
| 255 gboolean PanelDragGtk::OnButtonPressEvent(GtkWidget* widget, | 262 gboolean PanelDragGtk::OnButtonPressEvent(GtkWidget* widget, |
| 256 GdkEventButton* event) { | 263 GdkEventButton* event) { |
| 257 DCHECK(drag_delegate_); | 264 DCHECK(drag_delegate_ || drag_state_ == DRAG_ENDED_WAITING_FOR_MOUSE_RELEASE); |
| 258 return TRUE; | 265 return TRUE; |
| 259 } | 266 } |
| 260 | 267 |
| 261 gboolean PanelDragGtk::OnButtonReleaseEvent(GtkWidget* widget, | 268 gboolean PanelDragGtk::OnButtonReleaseEvent(GtkWidget* widget, |
| 262 GdkEventButton* event) { | 269 GdkEventButton* event) { |
| 263 DCHECK(drag_delegate_); | 270 DCHECK(drag_delegate_ || drag_state_ == DRAG_ENDED_WAITING_FOR_MOUSE_RELEASE); |
| 264 | |
| 265 if (event->button == 1) { | 271 if (event->button == 1) { |
| 266 // Treat release as a mouse click if drag was never started. | 272 // There will be no drag delegate if drag was canceled/ended using |
| 267 if (drag_state_ == NOT_DRAGGING && click_handler_) { | 273 // the keyboard before the mouse was released. |
| 268 gtk_propagate_event(click_handler_, | 274 if (drag_delegate_) { |
| 269 reinterpret_cast<GdkEvent*>(event)); | 275 // Treat release as a mouse click if drag was never started. |
| 276 if (drag_state_ == NOT_DRAGGING && click_handler_) { | |
| 277 gtk_propagate_event(click_handler_, | |
| 278 reinterpret_cast<GdkEvent*>(event)); | |
| 279 } | |
| 280 // Cleanup state regardless. | |
| 281 EndDrag(false); | |
| 282 } else { | |
| 283 DCHECK_EQ(DRAG_ENDED_WAITING_FOR_MOUSE_RELEASE, drag_state_); | |
| 270 } | 284 } |
| 271 // Cleanup state regardless. | 285 ReleasePointerAndKeyboardGrab(); |
| 272 EndDrag(false); | |
| 273 } | 286 } |
| 274 | 287 |
| 275 return TRUE; | 288 return TRUE; |
| 276 } | 289 } |
| 277 | 290 |
| 278 gboolean PanelDragGtk::OnKeyPressEvent(GtkWidget* widget, | 291 gboolean PanelDragGtk::OnKeyPressEvent(GtkWidget* widget, |
| 279 GdkEventKey* event) { | 292 GdkEventKey* event) { |
| 280 DCHECK(drag_delegate_); | 293 DCHECK(drag_delegate_ || drag_state_ == DRAG_ENDED_WAITING_FOR_MOUSE_RELEASE); |
| 281 return TRUE; | 294 return TRUE; |
| 282 } | 295 } |
| 283 | 296 |
| 284 gboolean PanelDragGtk::OnKeyReleaseEvent(GtkWidget* widget, | 297 gboolean PanelDragGtk::OnKeyReleaseEvent(GtkWidget* widget, |
| 285 GdkEventKey* event) { | 298 GdkEventKey* event) { |
| 286 DCHECK(drag_delegate_); | 299 DCHECK(drag_delegate_ || drag_state_ == DRAG_ENDED_WAITING_FOR_MOUSE_RELEASE); |
| 300 if (!drag_delegate_) | |
| 301 return TRUE; | |
| 287 | 302 |
| 288 switch (event->keyval) { | 303 switch (event->keyval) { |
| 289 case GDK_Escape: | 304 case GDK_Escape: |
| 290 EndDrag(true); // Cancel drag. | 305 EndDrag(true); // Cancel drag. |
| 291 break; | 306 break; |
| 292 case GDK_Return: | 307 case GDK_Return: |
| 293 case GDK_KP_Enter: | 308 case GDK_KP_Enter: |
| 294 case GDK_ISO_Enter: | 309 case GDK_ISO_Enter: |
| 295 case GDK_space: | 310 case GDK_space: |
| 296 EndDrag(false); // Normal end. | 311 EndDrag(false); // Normal end. |
| 297 break; | 312 break; |
| 298 } | 313 } |
| 299 return TRUE; | 314 return TRUE; |
| 300 } | 315 } |
| 301 | 316 |
| 302 gboolean PanelDragGtk::OnGrabBrokenEvent(GtkWidget* widget, | 317 gboolean PanelDragGtk::OnGrabBrokenEvent(GtkWidget* widget, |
| 303 GdkEventGrabBroken* event) { | 318 GdkEventGrabBroken* event) { |
| 304 DCHECK(drag_delegate_); | 319 DCHECK(drag_delegate_ || drag_state_ == DRAG_ENDED_WAITING_FOR_MOUSE_RELEASE); |
| 305 EndDrag(true); // Cancel drag. | 320 EndDrag(true); // Cancel drag. |
| 321 ReleasePointerAndKeyboardGrab(); | |
| 306 return TRUE; | 322 return TRUE; |
| 307 } | 323 } |
| OLD | NEW |