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

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: Update GTK native panel testing end drag logic. Created 8 years, 8 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() {
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
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 }
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