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

Side by Side Diff: chrome/browser/tab_contents/tab_contents_view_gtk.cc

Issue 159889: GTK: Fancy html5 draggy stuff. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 11 years, 4 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/tab_contents/tab_contents_view_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) 2009 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2009 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/tab_contents/tab_contents_view_gtk.h" 5 #include "chrome/browser/tab_contents/tab_contents_view_gtk.h"
6 6
7 #include <gdk/gdk.h> 7 #include <gdk/gdk.h>
8 #include <gdk/gdkkeysyms.h> 8 #include <gdk/gdkkeysyms.h>
9 #include <gtk/gtk.h> 9 #include <gtk/gtk.h>
10 10
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after
182 182
183 if (event->hardware_keycode < arraysize(kHardwareCodeToGdkKeyval)) { 183 if (event->hardware_keycode < arraysize(kHardwareCodeToGdkKeyval)) {
184 int keyval = kHardwareCodeToGdkKeyval[event->hardware_keycode]; 184 int keyval = kHardwareCodeToGdkKeyval[event->hardware_keycode];
185 if (keyval) 185 if (keyval)
186 return keyval; 186 return keyval;
187 } 187 }
188 188
189 return event->keyval; 189 return event->keyval;
190 } 190 }
191 191
192 // Get the current location of the mouse cursor relative to the screen.
193 gfx::Point ScreenPoint(GtkWidget* widget) {
194 int x, y;
195 gdk_display_get_pointer(gtk_widget_get_display(widget), NULL, &x, &y,
196 NULL);
197 return gfx::Point(x, y);
198 }
199
200 // Get the current location of the mouse cursor relative to the widget.
201 gfx::Point ClientPoint(GtkWidget* widget) {
202 int x, y;
203 gtk_widget_get_pointer(widget, &x, &y);
204 return gfx::Point(x, y);
205 }
206
192 } // namespace 207 } // namespace
193 208
194 // A helper class that handles DnD for drops in the renderer. In GTK parlance, 209 // A helper class that handles DnD for drops in the renderer. In GTK parlance,
195 // this handles destination-side DnD, but not source-side DnD. 210 // this handles destination-side DnD, but not source-side DnD.
196 class WebDragDest { 211 class WebDragDest {
197 public: 212 public:
198 explicit WebDragDest(TabContents* tab_contents, GtkWidget* widget) 213 explicit WebDragDest(TabContents* tab_contents, GtkWidget* widget)
199 : tab_contents_(tab_contents), 214 : tab_contents_(tab_contents),
200 widget_(widget), 215 widget_(widget),
201 context_(NULL), 216 context_(NULL),
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
280 }; 295 };
281 296
282 data_requests_ = arraysize(supported_targets); 297 data_requests_ = arraysize(supported_targets);
283 for (size_t i = 0; i < arraysize(supported_targets); ++i) { 298 for (size_t i = 0; i < arraysize(supported_targets); ++i) {
284 gtk_drag_get_data(widget_, context, 299 gtk_drag_get_data(widget_, context,
285 GtkDndUtil::GetAtomForTarget(supported_targets[i]), 300 GtkDndUtil::GetAtomForTarget(supported_targets[i]),
286 time); 301 time);
287 } 302 }
288 } else if (data_requests_ == 0) { 303 } else if (data_requests_ == 0) {
289 tab_contents_->render_view_host()-> 304 tab_contents_->render_view_host()->
290 DragTargetDragOver(ClientPoint(), ScreenPoint()); 305 DragTargetDragOver(ClientPoint(widget_), ScreenPoint(widget_));
291 drag_over_time_ = time; 306 drag_over_time_ = time;
292 } 307 }
293 308
294 // Pretend we are a drag destination because we don't want to wait for 309 // Pretend we are a drag destination because we don't want to wait for
295 // the renderer to tell us if we really are or not. 310 // the renderer to tell us if we really are or not.
296 return TRUE; 311 return TRUE;
297 } 312 }
298 313
299 // We make a series of requests for the drag data when the drag first enters 314 // We make a series of requests for the drag data when the drag first enters
300 // the render view. This is the callback that is used to give us the data 315 // the render view. This is the callback that is used to give us the data
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
341 drop_data_->text_html = UTF8ToUTF16(std::string( 356 drop_data_->text_html = UTF8ToUTF16(std::string(
342 reinterpret_cast<char*>(data->data), data->length)); 357 reinterpret_cast<char*>(data->data), data->length));
343 // We leave the base URL empty. 358 // We leave the base URL empty.
344 } 359 }
345 } 360 }
346 361
347 if (data_requests_ == 0) { 362 if (data_requests_ == 0) {
348 // Tell the renderer about the drag. 363 // Tell the renderer about the drag.
349 // |x| and |y| are seemingly arbitrary at this point. 364 // |x| and |y| are seemingly arbitrary at this point.
350 tab_contents_->render_view_host()-> 365 tab_contents_->render_view_host()->
351 DragTargetDragEnter(*drop_data_.get(), ClientPoint(), ScreenPoint()); 366 DragTargetDragEnter(*drop_data_.get(),
367 ClientPoint(widget_), ScreenPoint(widget_));
352 drag_over_time_ = time; 368 drag_over_time_ = time;
353 } 369 }
354 } 370 }
355 371
356 // The drag has left our widget; forward this information to the renderer. 372 // The drag has left our widget; forward this information to the renderer.
357 void OnDragLeave(GdkDragContext* context, guint time) { 373 void OnDragLeave(GdkDragContext* context, guint time) {
358 // Set |context_| to NULL to make sure we will recognize the next DragMotion 374 // Set |context_| to NULL to make sure we will recognize the next DragMotion
359 // as an enter. 375 // as an enter.
360 context_ = NULL; 376 context_ = NULL;
361 drop_data_.reset(); 377 drop_data_.reset();
362 // When GTK sends us a drag-drop signal, it is shortly (and synchronously) 378 // When GTK sends us a drag-drop signal, it is shortly (and synchronously)
363 // preceded by a drag-leave. The renderer doesn't like getting the signals 379 // preceded by a drag-leave. The renderer doesn't like getting the signals
364 // in this order so delay telling it about the drag-leave till we are sure 380 // in this order so delay telling it about the drag-leave till we are sure
365 // we are not getting a drop as well. 381 // we are not getting a drop as well.
366 MessageLoop::current()->PostTask(FROM_HERE, 382 MessageLoop::current()->PostTask(FROM_HERE,
367 method_factory_.NewRunnableMethod(&WebDragDest::DragLeave)); 383 method_factory_.NewRunnableMethod(&WebDragDest::DragLeave));
368 } 384 }
369 385
370 // Called by GTK when the user releases the mouse, executing a drop. 386 // Called by GTK when the user releases the mouse, executing a drop.
371 gboolean OnDragDrop(GdkDragContext* context, gint x, gint y, guint time) { 387 gboolean OnDragDrop(GdkDragContext* context, gint x, gint y, guint time) {
372 // Cancel that drag leave! 388 // Cancel that drag leave!
373 method_factory_.RevokeAll(); 389 method_factory_.RevokeAll();
374 390
375 tab_contents_->render_view_host()-> 391 tab_contents_->render_view_host()->
376 DragTargetDrop(ClientPoint(), ScreenPoint()); 392 DragTargetDrop(ClientPoint(widget_), ScreenPoint(widget_));
377 393
378 // The second parameter is just an educated guess, but at least we will 394 // The second parameter is just an educated guess, but at least we will
379 // get the drag-end animation right sometimes. 395 // get the drag-end animation right sometimes.
380 gtk_drag_finish(context, is_drop_target_, FALSE, time); 396 gtk_drag_finish(context, is_drop_target_, FALSE, time);
381 return TRUE; 397 return TRUE;
382 } 398 }
383 399
384 // Get the current location of the mouse cursor, relative to the screen.
385 gfx::Point ScreenPoint() {
386 int x, y;
387 gdk_display_get_pointer(gtk_widget_get_display(widget_), NULL, &x, &y,
388 NULL);
389 return gfx::Point(x, y);
390 }
391
392 // Get the current location of the mouse cursor, relative to the render view.
393 gfx::Point ClientPoint() {
394 int x, y;
395 gtk_widget_get_pointer(widget_, &x, &y);
396 return gfx::Point(x, y);
397 }
398 400
399 TabContents* tab_contents_; 401 TabContents* tab_contents_;
400 // The render view. 402 // The render view.
401 GtkWidget* widget_; 403 GtkWidget* widget_;
402 // The current drag context for system drags over our render view, or NULL if 404 // The current drag context for system drags over our render view, or NULL if
403 // there is no system drag or the system drag is not over our render view. 405 // there is no system drag or the system drag is not over our render view.
404 GdkDragContext* context_; 406 GdkDragContext* context_;
405 // The data for the current drag, or NULL if |context_| is NULL. 407 // The data for the current drag, or NULL if |context_| is NULL.
406 scoped_ptr<WebDropData> drop_data_; 408 scoped_ptr<WebDropData> drop_data_;
407 409
(...skipping 20 matching lines...) Expand all
428 430
429 // static 431 // static
430 TabContentsView* TabContentsView::Create(TabContents* tab_contents) { 432 TabContentsView* TabContentsView::Create(TabContents* tab_contents) {
431 return new TabContentsViewGtk(tab_contents); 433 return new TabContentsViewGtk(tab_contents);
432 } 434 }
433 435
434 TabContentsViewGtk::TabContentsViewGtk(TabContents* tab_contents) 436 TabContentsViewGtk::TabContentsViewGtk(TabContents* tab_contents)
435 : TabContentsView(tab_contents), 437 : TabContentsView(tab_contents),
436 floating_(gtk_floating_container_new()), 438 floating_(gtk_floating_container_new()),
437 fixed_(gtk_fixed_new()), 439 fixed_(gtk_fixed_new()),
438 popup_view_(NULL) { 440 popup_view_(NULL),
441 drag_failed_(false),
442 drag_widget_(NULL) {
439 g_signal_connect(fixed_, "size-allocate", 443 g_signal_connect(fixed_, "size-allocate",
440 G_CALLBACK(OnSizeAllocate), this); 444 G_CALLBACK(OnSizeAllocate), this);
441 g_signal_connect(floating_.get(), "set-floating-position", 445 g_signal_connect(floating_.get(), "set-floating-position",
442 G_CALLBACK(OnSetFloatingPosition), this); 446 G_CALLBACK(OnSetFloatingPosition), this);
443 447
444 gtk_container_add(GTK_CONTAINER(floating_.get()), fixed_); 448 gtk_container_add(GTK_CONTAINER(floating_.get()), fixed_);
445 gtk_widget_show(fixed_); 449 gtk_widget_show(fixed_);
446 gtk_widget_show(floating_.get()); 450 gtk_widget_show(floating_.get());
447 registrar_.Add(this, NotificationType::TAB_CONTENTS_CONNECTED, 451 registrar_.Add(this, NotificationType::TAB_CONTENTS_CONNECTED,
448 Source<TabContents>(tab_contents)); 452 Source<TabContents>(tab_contents));
453
454 // Renderer source DnD.
455 drag_widget_ = gtk_invisible_new();
456 g_signal_connect(drag_widget_, "drag-failed",
457 G_CALLBACK(OnDragFailedThunk), this);
458 g_signal_connect(drag_widget_, "drag-end", G_CALLBACK(OnDragEndThunk), this);
459 g_signal_connect(drag_widget_, "drag-data-get",
460 G_CALLBACK(OnDragDataGetThunk), this);
461 g_object_ref_sink(drag_widget_);
449 } 462 }
450 463
451 TabContentsViewGtk::~TabContentsViewGtk() { 464 TabContentsViewGtk::~TabContentsViewGtk() {
452 floating_.Destroy(); 465 floating_.Destroy();
453 } 466 }
454 467
455 void TabContentsViewGtk::AttachBlockedPopupView( 468 void TabContentsViewGtk::AttachBlockedPopupView(
456 BlockedPopupContainerViewGtk* popup_view) { 469 BlockedPopupContainerViewGtk* popup_view) {
457 DCHECK(popup_view_ == NULL); 470 DCHECK(popup_view_ == NULL);
458 popup_view_ = popup_view; 471 popup_view_ = popup_view;
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
515 g_signal_connect(content_view, "leave-notify-event", 528 g_signal_connect(content_view, "leave-notify-event",
516 G_CALLBACK(OnLeaveNotify), tab_contents()); 529 G_CALLBACK(OnLeaveNotify), tab_contents());
517 g_signal_connect(content_view, "motion-notify-event", 530 g_signal_connect(content_view, "motion-notify-event",
518 G_CALLBACK(OnMouseMove), tab_contents()); 531 G_CALLBACK(OnMouseMove), tab_contents());
519 g_signal_connect(content_view, "scroll-event", 532 g_signal_connect(content_view, "scroll-event",
520 G_CALLBACK(OnMouseScroll), tab_contents()); 533 G_CALLBACK(OnMouseScroll), tab_contents());
521 gtk_widget_add_events(content_view, GDK_LEAVE_NOTIFY_MASK | 534 gtk_widget_add_events(content_view, GDK_LEAVE_NOTIFY_MASK |
522 GDK_POINTER_MOTION_MASK); 535 GDK_POINTER_MOTION_MASK);
523 g_signal_connect(content_view, "button-press-event", 536 g_signal_connect(content_view, "button-press-event",
524 G_CALLBACK(OnMouseDown), this); 537 G_CALLBACK(OnMouseDown), this);
538 InsertIntoContentArea(content_view);
525 539
526 // Renderer DnD. 540 // Renderer target DnD.
527 g_signal_connect(content_view, "drag-end", G_CALLBACK(OnDragEnd), this);
528 g_signal_connect(content_view, "drag-data-get", G_CALLBACK(OnDragDataGet),
529 this);
530 drag_dest_.reset(new WebDragDest(tab_contents(), content_view)); 541 drag_dest_.reset(new WebDragDest(tab_contents(), content_view));
531 542
532 InsertIntoContentArea(content_view);
533 return view; 543 return view;
534 } 544 }
535 545
536 gfx::NativeView TabContentsViewGtk::GetNativeView() const { 546 gfx::NativeView TabContentsViewGtk::GetNativeView() const {
537 return floating_.get(); 547 return floating_.get();
538 } 548 }
539 549
540 gfx::NativeView TabContentsViewGtk::GetContentNativeView() const { 550 gfx::NativeView TabContentsViewGtk::GetContentNativeView() const {
541 if (!tab_contents()->render_widget_host_view()) 551 if (!tab_contents()->render_widget_host_view())
542 return NULL; 552 return NULL;
543 return tab_contents()->render_widget_host_view()->GetNativeView(); 553 return tab_contents()->render_widget_host_view()->GetNativeView();
544 } 554 }
545 555
546
547 gfx::NativeWindow TabContentsViewGtk::GetTopLevelNativeWindow() const { 556 gfx::NativeWindow TabContentsViewGtk::GetTopLevelNativeWindow() const {
548 GtkWidget* window = gtk_widget_get_ancestor(GetNativeView(), GTK_TYPE_WINDOW); 557 GtkWidget* window = gtk_widget_get_ancestor(GetNativeView(), GTK_TYPE_WINDOW);
549 return window ? GTK_WINDOW(window) : NULL; 558 return window ? GTK_WINDOW(window) : NULL;
550 } 559 }
551 560
552 void TabContentsViewGtk::InitRendererPrefs(RendererPreferences* prefs) { 561 void TabContentsViewGtk::InitRendererPrefs(RendererPreferences* prefs) {
553 GtkSettings* gtk_settings = gtk_settings_get_default(); 562 GtkSettings* gtk_settings = gtk_settings_get_default();
554 563
555 gint antialias = 0; 564 gint antialias = 0;
556 gint hinting = 0; 565 gint hinting = 0;
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
605 // animation. 614 // animation.
606 int x = 0; 615 int x = 0;
607 int y = 0; 616 int y = 0;
608 if (fixed_->window) 617 if (fixed_->window)
609 gdk_window_get_origin(fixed_->window, &x, &y); 618 gdk_window_get_origin(fixed_->window, &x, &y);
610 out->SetRect(x + fixed_->allocation.x, y + fixed_->allocation.y, 619 out->SetRect(x + fixed_->allocation.x, y + fixed_->allocation.y,
611 fixed_->allocation.width, fixed_->allocation.height); 620 fixed_->allocation.width, fixed_->allocation.height);
612 } 621 }
613 622
614 void TabContentsViewGtk::OnContentsDestroy() { 623 void TabContentsViewGtk::OnContentsDestroy() {
615 // TODO(estade): Windows uses this for some sort of plugin-related stuff. 624 // We don't want to try to handle drag events from this point on.
625 g_signal_handlers_disconnect_by_func(drag_widget_,
626 reinterpret_cast<gpointer>(OnDragFailedThunk), this);
627 g_signal_handlers_disconnect_by_func(drag_widget_,
628 reinterpret_cast<gpointer>(OnDragEndThunk), this);
629 g_signal_handlers_disconnect_by_func(drag_widget_,
630 reinterpret_cast<gpointer>(OnDragDataGetThunk), this);
631
632 // Break the current drag, if any.
633 if (drop_data_.get()) {
634 gtk_grab_add(drag_widget_);
635 gtk_grab_remove(drag_widget_);
636 MessageLoopForUI::current()->RemoveObserver(this);
637 drop_data_.reset();
638 }
639
640 gtk_widget_destroy(drag_widget_);
641 g_object_unref(drag_widget_);
642 drag_widget_ = NULL;
616 } 643 }
617 644
618 void TabContentsViewGtk::SetPageTitle(const std::wstring& title) { 645 void TabContentsViewGtk::SetPageTitle(const std::wstring& title) {
619 // Set the window name to include the page title so it's easier to spot 646 // Set the window name to include the page title so it's easier to spot
620 // when debugging (e.g. via xwininfo -tree). 647 // when debugging (e.g. via xwininfo -tree).
621 gfx::NativeView content_view = GetContentNativeView(); 648 gfx::NativeView content_view = GetContentNativeView();
622 if (content_view && content_view->window) 649 if (content_view && content_view->window)
623 gdk_window_set_title(content_view->window, WideToUTF8(title).c_str()); 650 gdk_window_set_title(content_view->window, WideToUTF8(title).c_str());
624 } 651 }
625 652
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
715 // vbox's children. 742 // vbox's children.
716 sad_tab_.reset(); 743 sad_tab_.reset();
717 break; 744 break;
718 } 745 }
719 default: 746 default:
720 NOTREACHED() << "Got a notification we didn't register for."; 747 NOTREACHED() << "Got a notification we didn't register for.";
721 break; 748 break;
722 } 749 }
723 } 750 }
724 751
752 void TabContentsViewGtk::WillProcessEvent(GdkEvent* event) {
753 // No-op.
754 }
755
756 void TabContentsViewGtk::DidProcessEvent(GdkEvent* event) {
757 if (event->type != GDK_MOTION_NOTIFY)
758 return;
759
760 GdkEventMotion* event_motion = reinterpret_cast<GdkEventMotion*>(event);
761 gfx::Point client = ClientPoint(GetContentNativeView());
762
763 if (tab_contents()->render_view_host()) {
764 tab_contents()->render_view_host()->DragSourceMovedTo(
765 client.x(), client.y(), event_motion->x_root, event_motion->y_root);
766 }
767 }
768
725 void TabContentsViewGtk::ShowContextMenu(const ContextMenuParams& params) { 769 void TabContentsViewGtk::ShowContextMenu(const ContextMenuParams& params) {
726 context_menu_.reset(new RenderViewContextMenuGtk(tab_contents(), params, 770 context_menu_.reset(new RenderViewContextMenuGtk(tab_contents(), params,
727 last_mouse_down_.time)); 771 last_mouse_down_.time));
728 context_menu_->Init(); 772 context_menu_->Init();
729 context_menu_->Popup(); 773 context_menu_->Popup();
730 } 774 }
731 775
732 // Render view DnD ------------------------------------------------------------- 776 // Render view DnD -------------------------------------------------------------
733 777
734 void TabContentsViewGtk::DragEnded() {
735 if (tab_contents()->render_view_host())
736 tab_contents()->render_view_host()->DragSourceSystemDragEnded();
737 }
738
739 void TabContentsViewGtk::StartDragging(const WebDropData& drop_data) { 778 void TabContentsViewGtk::StartDragging(const WebDropData& drop_data) {
740 DCHECK(GetContentNativeView()); 779 DCHECK(GetContentNativeView());
741 780
742 int targets_mask = 0; 781 int targets_mask = 0;
743 782
744 if (!drop_data.plain_text.empty()) 783 if (!drop_data.plain_text.empty())
745 targets_mask |= GtkDndUtil::TEXT_PLAIN; 784 targets_mask |= GtkDndUtil::TEXT_PLAIN;
746 if (drop_data.url.is_valid()) { 785 if (drop_data.url.is_valid()) {
747 targets_mask |= GtkDndUtil::TEXT_URI_LIST; 786 targets_mask |= GtkDndUtil::TEXT_URI_LIST;
748 targets_mask |= GtkDndUtil::CHROME_NAMED_URL; 787 targets_mask |= GtkDndUtil::CHROME_NAMED_URL;
749 } 788 }
750 if (!drop_data.text_html.empty()) 789 if (!drop_data.text_html.empty())
751 targets_mask |= GtkDndUtil::TEXT_HTML; 790 targets_mask |= GtkDndUtil::TEXT_HTML;
752 if (!drop_data.file_contents.empty()) 791 if (!drop_data.file_contents.empty())
753 targets_mask |= GtkDndUtil::CHROME_WEBDROP_FILE_CONTENTS; 792 targets_mask |= GtkDndUtil::CHROME_WEBDROP_FILE_CONTENTS;
754 793
755 if (targets_mask == 0) { 794 if (targets_mask == 0) {
756 NOTIMPLEMENTED(); 795 NOTIMPLEMENTED();
757 DragEnded(); 796 if (tab_contents()->render_view_host())
758 return; 797 tab_contents()->render_view_host()->DragSourceSystemDragEnded();
759 } 798 }
760 799
761 drop_data_.reset(new WebDropData(drop_data)); 800 drop_data_.reset(new WebDropData(drop_data));
762 801
763 GtkTargetList* list = GtkDndUtil::GetTargetListFromCodeMask(targets_mask); 802 GtkTargetList* list = GtkDndUtil::GetTargetListFromCodeMask(targets_mask);
764 if (targets_mask & GtkDndUtil::CHROME_WEBDROP_FILE_CONTENTS) { 803 if (targets_mask & GtkDndUtil::CHROME_WEBDROP_FILE_CONTENTS) {
765 drag_file_mime_type_ = gdk_atom_intern( 804 drag_file_mime_type_ = gdk_atom_intern(
766 mime_util::GetDataMimeType(drop_data.file_contents).c_str(), FALSE); 805 mime_util::GetDataMimeType(drop_data.file_contents).c_str(), FALSE);
767 gtk_target_list_add(list, drag_file_mime_type_, 806 gtk_target_list_add(list, drag_file_mime_type_,
768 0, GtkDndUtil::CHROME_WEBDROP_FILE_CONTENTS); 807 0, GtkDndUtil::CHROME_WEBDROP_FILE_CONTENTS);
769 } 808 }
770 809
810 drag_failed_ = false;
771 // If we don't pass an event, GDK won't know what event time to start grabbing 811 // If we don't pass an event, GDK won't know what event time to start grabbing
772 // mouse events. Technically it's the mouse motion event and not the mouse 812 // mouse events. Technically it's the mouse motion event and not the mouse
773 // down event that causes the drag, but there's no reliable way to know 813 // down event that causes the drag, but there's no reliable way to know
774 // *which* motion event initiated the drag, so this will have to do. 814 // *which* motion event initiated the drag, so this will have to do.
775 // TODO(estade): This can sometimes be very far off, e.g. if the user clicks 815 // TODO(estade): This can sometimes be very far off, e.g. if the user clicks
776 // and holds and doesn't start dragging for a long time. I doubt it matters 816 // and holds and doesn't start dragging for a long time. I doubt it matters
777 // much, but we should probably look into the possibility of getting the 817 // much, but we should probably look into the possibility of getting the
778 // initiating event from webkit. 818 // initiating event from webkit.
779 gtk_drag_begin(GetContentNativeView(), list, GDK_ACTION_COPY, 819 gtk_drag_begin(drag_widget_, list, GDK_ACTION_COPY,
780 1, // Drags are always initiated by the left button. 820 1, // Drags are always initiated by the left button.
781 reinterpret_cast<GdkEvent*>(&last_mouse_down_)); 821 reinterpret_cast<GdkEvent*>(&last_mouse_down_));
822 MessageLoopForUI::current()->AddObserver(this);
782 // The drag adds a ref; let it own the list. 823 // The drag adds a ref; let it own the list.
783 gtk_target_list_unref(list); 824 gtk_target_list_unref(list);
784 } 825 }
785 826
786 // static
787 void TabContentsViewGtk::OnDragDataGet( 827 void TabContentsViewGtk::OnDragDataGet(
788 GtkWidget* drag_widget,
789 GdkDragContext* context, GtkSelectionData* selection_data, 828 GdkDragContext* context, GtkSelectionData* selection_data,
790 guint target_type, guint time, TabContentsViewGtk* view) { 829 guint target_type, guint time) {
791 const int bits_per_byte = 8; 830 const int bits_per_byte = 8;
792 831
793 switch (target_type) { 832 switch (target_type) {
794 case GtkDndUtil::TEXT_PLAIN: { 833 case GtkDndUtil::TEXT_PLAIN: {
795 std::string utf8_text = UTF16ToUTF8(view->drop_data_->plain_text); 834 std::string utf8_text = UTF16ToUTF8(drop_data_->plain_text);
796 gtk_selection_data_set_text(selection_data, utf8_text.c_str(), 835 gtk_selection_data_set_text(selection_data, utf8_text.c_str(),
797 utf8_text.length()); 836 utf8_text.length());
798 break; 837 break;
799 } 838 }
800 839
801 case GtkDndUtil::TEXT_URI_LIST: { 840 case GtkDndUtil::TEXT_URI_LIST: {
802 gchar* uri_array[2]; 841 gchar* uri_array[2];
803 uri_array[0] = strdup(view->drop_data_->url.spec().c_str()); 842 uri_array[0] = strdup(drop_data_->url.spec().c_str());
804 uri_array[1] = NULL; 843 uri_array[1] = NULL;
805 gtk_selection_data_set_uris(selection_data, uri_array); 844 gtk_selection_data_set_uris(selection_data, uri_array);
806 free(uri_array[0]); 845 free(uri_array[0]);
807 break; 846 break;
808 } 847 }
809 848
810 case GtkDndUtil::TEXT_HTML: { 849 case GtkDndUtil::TEXT_HTML: {
811 // TODO(estade): change relative links to be absolute using 850 // TODO(estade): change relative links to be absolute using
812 // |html_base_url|. 851 // |html_base_url|.
813 std::string utf8_text = UTF16ToUTF8(view->drop_data_->text_html); 852 std::string utf8_text = UTF16ToUTF8(drop_data_->text_html);
814 gtk_selection_data_set(selection_data, 853 gtk_selection_data_set(selection_data,
815 GtkDndUtil::GetAtomForTarget(GtkDndUtil::TEXT_HTML), 854 GtkDndUtil::GetAtomForTarget(GtkDndUtil::TEXT_HTML),
816 bits_per_byte, 855 bits_per_byte,
817 reinterpret_cast<const guchar*>(utf8_text.c_str()), 856 reinterpret_cast<const guchar*>(utf8_text.c_str()),
818 utf8_text.length()); 857 utf8_text.length());
819 break; 858 break;
820 } 859 }
821 860
822 case GtkDndUtil::CHROME_NAMED_URL: { 861 case GtkDndUtil::CHROME_NAMED_URL: {
823 Pickle pickle; 862 Pickle pickle;
824 pickle.WriteString(UTF16ToUTF8(view->drop_data_->url_title)); 863 pickle.WriteString(UTF16ToUTF8(drop_data_->url_title));
825 pickle.WriteString(view->drop_data_->url.spec()); 864 pickle.WriteString(drop_data_->url.spec());
826 gtk_selection_data_set(selection_data, 865 gtk_selection_data_set(selection_data,
827 GtkDndUtil::GetAtomForTarget(GtkDndUtil::CHROME_NAMED_URL), 866 GtkDndUtil::GetAtomForTarget(GtkDndUtil::CHROME_NAMED_URL),
828 bits_per_byte, 867 bits_per_byte,
829 reinterpret_cast<const guchar*>(pickle.data()), 868 reinterpret_cast<const guchar*>(pickle.data()),
830 pickle.size()); 869 pickle.size());
831 break; 870 break;
832 } 871 }
833 872
834 case GtkDndUtil::CHROME_WEBDROP_FILE_CONTENTS: { 873 case GtkDndUtil::CHROME_WEBDROP_FILE_CONTENTS: {
835 gtk_selection_data_set(selection_data, 874 gtk_selection_data_set(selection_data,
836 view->drag_file_mime_type_, bits_per_byte, 875 drag_file_mime_type_, bits_per_byte,
837 reinterpret_cast<const guchar*>( 876 reinterpret_cast<const guchar*>(drop_data_->file_contents.data()),
838 view->drop_data_->file_contents.data()), 877 drop_data_->file_contents.length());
839 view->drop_data_->file_contents.length());
840 break; 878 break;
841 } 879 }
842 880
843 default: 881 default:
844 NOTREACHED(); 882 NOTREACHED();
845 } 883 }
846 } 884 }
847 885
848 // static 886 gboolean TabContentsViewGtk::OnDragFailed() {
849 void TabContentsViewGtk::OnDragEnd(GtkWidget* widget, 887 drag_failed_ = true;
850 GdkDragContext* drag_context, TabContentsViewGtk* view) { 888
851 view->DragEnded(); 889 gfx::Point root = ScreenPoint(GetContentNativeView());
852 view->drop_data_.reset(); 890 gfx::Point client = ClientPoint(GetContentNativeView());
891
892 if (tab_contents()->render_view_host()) {
893 tab_contents()->render_view_host()->DragSourceCancelledAt(
894 client.x(), client.y(), root.x(), root.y());
895 }
896
897 // Let the native failure animation run.
898 return FALSE;
899 }
900
901 void TabContentsViewGtk::OnDragEnd() {
902 MessageLoopForUI::current()->RemoveObserver(this);
903
904 if (!drag_failed_) {
905 gfx::Point root = ScreenPoint(GetContentNativeView());
906 gfx::Point client = ClientPoint(GetContentNativeView());
907
908 if (tab_contents()->render_view_host()) {
909 tab_contents()->render_view_host()->DragSourceEndedAt(
910 client.x(), client.y(), root.x(), root.y());
911 }
912 }
913
914 if (tab_contents()->render_view_host())
915 tab_contents()->render_view_host()->DragSourceSystemDragEnded();
916
917 drop_data_.reset();
853 } 918 }
854 919
855 // ----------------------------------------------------------------------------- 920 // -----------------------------------------------------------------------------
856 921
857 void TabContentsViewGtk::InsertIntoContentArea(GtkWidget* widget) { 922 void TabContentsViewGtk::InsertIntoContentArea(GtkWidget* widget) {
858 gtk_fixed_put(GTK_FIXED(fixed_), widget, 0, 0); 923 gtk_fixed_put(GTK_FIXED(fixed_), widget, 0, 0);
859 } 924 }
860 925
861 gboolean TabContentsViewGtk::OnMouseDown(GtkWidget* widget, 926 gboolean TabContentsViewGtk::OnMouseDown(GtkWidget* widget,
862 GdkEventButton* event, TabContentsViewGtk* view) { 927 GdkEventButton* event, TabContentsViewGtk* view) {
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
930 gtk_container_child_set_property(GTK_CONTAINER(floating_container), 995 gtk_container_child_set_property(GTK_CONTAINER(floating_container),
931 widget, "x", &value); 996 widget, "x", &value);
932 997
933 int child_y = std::max(half_view_height - (requisition.height / 2), 0); 998 int child_y = std::max(half_view_height - (requisition.height / 2), 0);
934 g_value_set_int(&value, child_y); 999 g_value_set_int(&value, child_y);
935 gtk_container_child_set_property(GTK_CONTAINER(floating_container), 1000 gtk_container_child_set_property(GTK_CONTAINER(floating_container),
936 widget, "y", &value); 1001 widget, "y", &value);
937 g_value_unset(&value); 1002 g_value_unset(&value);
938 } 1003 }
939 } 1004 }
OLDNEW
« no previous file with comments | « chrome/browser/tab_contents/tab_contents_view_gtk.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698