| OLD | NEW |
| 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 <gtk/gtk.h> | 8 #include <gtk/gtk.h> |
| 9 | 9 |
| 10 #include "base/mime_util.h" | 10 #include "base/mime_util.h" |
| (...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 172 dest->OnDragDataReceived(drag_context, x, y, data, info, time); | 172 dest->OnDragDataReceived(drag_context, x, y, data, info, time); |
| 173 } | 173 } |
| 174 | 174 |
| 175 // Called when a system drag crosses over the render view. As there is no drag | 175 // Called when a system drag crosses over the render view. As there is no drag |
| 176 // enter event, we treat it as an enter event (and not a regular motion event) | 176 // enter event, we treat it as an enter event (and not a regular motion event) |
| 177 // when |context_| is NULL. | 177 // when |context_| is NULL. |
| 178 gboolean OnDragMotion(GdkDragContext* context, gint x, gint y, guint time) { | 178 gboolean OnDragMotion(GdkDragContext* context, gint x, gint y, guint time) { |
| 179 if (context_ != context) { | 179 if (context_ != context) { |
| 180 context_ = context; | 180 context_ = context; |
| 181 drop_data_.reset(new WebDropData); | 181 drop_data_.reset(new WebDropData); |
| 182 data_requests_ = 0; | |
| 183 is_drop_target_ = false; | 182 is_drop_target_ = false; |
| 184 | 183 |
| 185 // TODO(estade): support other targets. When we start support URL drags, | 184 static int supported_targets[] = { |
| 186 // we'll have to worry about interstitial pages (see web_drop_target.cc). | 185 GtkDndUtil::X_CHROME_TEXT_PLAIN, |
| 187 data_requests_++; | 186 GtkDndUtil::X_CHROME_TEXT_URI_LIST, |
| 188 gtk_drag_get_data(widget_, context, | 187 GtkDndUtil::X_CHROME_TEXT_HTML, |
| 189 gdk_atom_intern("text/plain", FALSE), time); | 188 // TODO(estade): support image drags? |
| 189 }; |
| 190 |
| 191 data_requests_ = arraysize(supported_targets); |
| 192 for (size_t i = 0; i < arraysize(supported_targets); ++i) { |
| 193 gtk_drag_get_data(widget_, context, |
| 194 GtkDndUtil::GetAtomForTarget(supported_targets[i]), |
| 195 time); |
| 196 } |
| 190 } else if (data_requests_ == 0) { | 197 } else if (data_requests_ == 0) { |
| 191 tab_contents_->render_view_host()-> | 198 tab_contents_->render_view_host()-> |
| 192 DragTargetDragOver(ClientPoint(), ScreenPoint()); | 199 DragTargetDragOver(ClientPoint(), ScreenPoint()); |
| 193 drag_over_time_ = time; | 200 drag_over_time_ = time; |
| 194 } | 201 } |
| 195 | 202 |
| 196 // Pretend we are a drag destination because we don't want to wait for | 203 // Pretend we are a drag destination because we don't want to wait for |
| 197 // the renderer to tell us if we really are or not. | 204 // the renderer to tell us if we really are or not. |
| 198 return TRUE; | 205 return TRUE; |
| 199 } | 206 } |
| 200 | 207 |
| 201 // We make a series of requests for the drag data when the drag first enters | 208 // We make a series of requests for the drag data when the drag first enters |
| 202 // the render view. This is the callback that is used to give us the data | 209 // the render view. This is the callback that is used to give us the data |
| 203 // for each individual target. When |data_requests_| reaches 0, we know we | 210 // for each individual target. When |data_requests_| reaches 0, we know we |
| 204 // have attained all the data, and we can finally tell the renderer about the | 211 // have attained all the data, and we can finally tell the renderer about the |
| 205 // drag. | 212 // drag. |
| 206 void OnDragDataReceived(GdkDragContext* context, gint x, gint y, | 213 void OnDragDataReceived(GdkDragContext* context, gint x, gint y, |
| 207 GtkSelectionData* data, guint info, guint time) { | 214 GtkSelectionData* data, guint info, guint time) { |
| 208 // We might get the data from an old get_data() request that we no longer | 215 // We might get the data from an old get_data() request that we no longer |
| 209 // care about. | 216 // care about. |
| 210 if (context != context_) | 217 if (context != context_) |
| 211 return; | 218 return; |
| 212 | 219 |
| 213 data_requests_--; | 220 data_requests_--; |
| 214 | 221 |
| 215 // If the source can't provide us with valid data for a requested target, | 222 // Decode the data. |
| 216 // data->data will be NULL. | |
| 217 if (data->data) { | 223 if (data->data) { |
| 218 drop_data_->plain_text = UTF8ToUTF16(std::string( | 224 // If the source can't provide us with valid data for a requested target, |
| 219 reinterpret_cast<char*>(data->data), data->length)); | 225 // data->data will be NULL. |
| 226 if (data->target == |
| 227 GtkDndUtil::GetAtomForTarget(GtkDndUtil::X_CHROME_TEXT_PLAIN)) { |
| 228 guchar* text = gtk_selection_data_get_text(data); |
| 229 if (text) { |
| 230 drop_data_->plain_text = UTF8ToUTF16(std::string( |
| 231 reinterpret_cast<char*>(text), data->length)); |
| 232 g_free(text); |
| 233 } |
| 234 } else if (data->target == |
| 235 GtkDndUtil::GetAtomForTarget(GtkDndUtil::X_CHROME_TEXT_URI_LIST)) { |
| 236 gchar** uris = gtk_selection_data_get_uris(data); |
| 237 if (uris) { |
| 238 for (gchar** uri_iter = uris; *uri_iter; uri_iter++) { |
| 239 // TODO(estade): Can the filenames have a non-UTF8 encoding? |
| 240 drop_data_->filenames.push_back(UTF8ToUTF16(*uri_iter)); |
| 241 } |
| 242 // Also, write the first URI as the URL. |
| 243 if (uris[0]) |
| 244 drop_data_->url = GURL(uris[0]); |
| 245 g_strfreev(uris); |
| 246 } |
| 247 } else if (data->target == |
| 248 GtkDndUtil::GetAtomForTarget(GtkDndUtil::X_CHROME_TEXT_HTML)) { |
| 249 // TODO(estade): Can the html have a non-UTF8 encoding? |
| 250 drop_data_->text_html = UTF8ToUTF16(std::string( |
| 251 reinterpret_cast<char*>(data->data), data->length)); |
| 252 // We leave the base URL empty. |
| 253 } |
| 220 } | 254 } |
| 221 | 255 |
| 222 if (data_requests_ == 0) { | 256 if (data_requests_ == 0) { |
| 257 // Tell the renderer about the drag. |
| 223 // |x| and |y| are seemingly arbitrary at this point. | 258 // |x| and |y| are seemingly arbitrary at this point. |
| 224 tab_contents_->render_view_host()-> | 259 tab_contents_->render_view_host()-> |
| 225 DragTargetDragEnter(*drop_data_.get(), ClientPoint(), ScreenPoint()); | 260 DragTargetDragEnter(*drop_data_.get(), ClientPoint(), ScreenPoint()); |
| 226 drag_over_time_ = time; | 261 drag_over_time_ = time; |
| 227 } | 262 } |
| 228 } | 263 } |
| 229 | 264 |
| 230 // The drag has left our widget; forward this information to the renderer. | 265 // The drag has left our widget; forward this information to the renderer. |
| 231 void OnDragLeave(GdkDragContext* context, guint time) { | 266 void OnDragLeave(GdkDragContext* context, guint time) { |
| 232 // Set |context_| to NULL to make sure we will recognize the next DragMotion | 267 // Set |context_| to NULL to make sure we will recognize the next DragMotion |
| (...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 430 // animation. | 465 // animation. |
| 431 int x = 0; | 466 int x = 0; |
| 432 int y = 0; | 467 int y = 0; |
| 433 if (fixed_->window) | 468 if (fixed_->window) |
| 434 gdk_window_get_origin(fixed_->window, &x, &y); | 469 gdk_window_get_origin(fixed_->window, &x, &y); |
| 435 out->SetRect(x + fixed_->allocation.x, y + fixed_->allocation.y, | 470 out->SetRect(x + fixed_->allocation.x, y + fixed_->allocation.y, |
| 436 fixed_->allocation.width, fixed_->allocation.height); | 471 fixed_->allocation.width, fixed_->allocation.height); |
| 437 } | 472 } |
| 438 | 473 |
| 439 void TabContentsViewGtk::OnContentsDestroy() { | 474 void TabContentsViewGtk::OnContentsDestroy() { |
| 440 // TODO(estade): Windows uses this function cancel pending drag-n-drop drags. | 475 // TODO(estade): Windows uses this for some sort of plugin-related stuff. |
| 441 // We don't have drags yet, so do nothing for now. | |
| 442 } | 476 } |
| 443 | 477 |
| 444 void TabContentsViewGtk::SetPageTitle(const std::wstring& title) { | 478 void TabContentsViewGtk::SetPageTitle(const std::wstring& title) { |
| 445 // Set the window name to include the page title so it's easier to spot | 479 // Set the window name to include the page title so it's easier to spot |
| 446 // when debugging (e.g. via xwininfo -tree). | 480 // when debugging (e.g. via xwininfo -tree). |
| 447 gfx::NativeView content_view = GetContentNativeView(); | 481 gfx::NativeView content_view = GetContentNativeView(); |
| 448 if (content_view && content_view->window) | 482 if (content_view && content_view->window) |
| 449 gdk_window_set_title(content_view->window, WideToUTF8(title).c_str()); | 483 gdk_window_set_title(content_view->window, WideToUTF8(title).c_str()); |
| 450 } | 484 } |
| 451 | 485 |
| (...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 734 gtk_container_child_set_property(GTK_CONTAINER(floating_container), | 768 gtk_container_child_set_property(GTK_CONTAINER(floating_container), |
| 735 widget, "x", &value); | 769 widget, "x", &value); |
| 736 | 770 |
| 737 int child_y = std::max(half_view_height - (requisition.height / 2), 0); | 771 int child_y = std::max(half_view_height - (requisition.height / 2), 0); |
| 738 g_value_set_int(&value, child_y); | 772 g_value_set_int(&value, child_y); |
| 739 gtk_container_child_set_property(GTK_CONTAINER(floating_container), | 773 gtk_container_child_set_property(GTK_CONTAINER(floating_container), |
| 740 widget, "y", &value); | 774 widget, "y", &value); |
| 741 g_value_unset(&value); | 775 g_value_unset(&value); |
| 742 } | 776 } |
| 743 } | 777 } |
| OLD | NEW |