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

Side by Side Diff: chrome/browser/ui/panels/panel_drag_gtk.cc

Issue 10170037: Make GTK Panels ignore mouse/keyboard events after drag is ended until mouse is released. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 7 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 | « chrome/browser/ui/panels/panel_drag_gtk.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 "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
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
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
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 }
OLDNEW
« no previous file with comments | « chrome/browser/ui/panels/panel_drag_gtk.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698