Index: content/renderer/gpu/render_widget_compositor.cc |
diff --git a/content/renderer/gpu/render_widget_compositor.cc b/content/renderer/gpu/render_widget_compositor.cc |
index eac6a28184f6aba654619f5270cb5cb9b174128d..d642b31a7ac9709e202ec41c6a1253335cecd017 100644 |
--- a/content/renderer/gpu/render_widget_compositor.cc |
+++ b/content/renderer/gpu/render_widget_compositor.cc |
@@ -25,6 +25,7 @@ |
#include "cc/layers/layer.h" |
#include "cc/output/copy_output_request.h" |
#include "cc/output/copy_output_result.h" |
+#include "cc/output/selection_handle.h" |
#include "cc/resources/single_release_callback.h" |
#include "cc/trees/layer_tree_host.h" |
#include "content/child/child_shared_bitmap_manager.h" |
@@ -36,6 +37,7 @@ |
#include "gpu/command_buffer/client/gles2_interface.h" |
#include "third_party/WebKit/public/platform/WebCompositeAndReadbackAsyncCallback.h" |
#include "third_party/WebKit/public/platform/WebSize.h" |
+#include "third_party/WebKit/public/web/WebSelection.h" |
#include "third_party/WebKit/public/web/WebWidget.h" |
#include "ui/gfx/frame_time.h" |
#include "ui/gl/gl_switches.h" |
@@ -51,6 +53,7 @@ class Layer; |
} |
using blink::WebFloatPoint; |
+using blink::WebSelection; |
using blink::WebSize; |
using blink::WebRect; |
@@ -76,6 +79,46 @@ bool GetSwitchValueAsInt( |
} |
} |
+bool ConvertWebSelection(const WebSelection& selection, |
+ cc::Layer** start_layer, |
+ cc::SelectionHandle* start_handle, |
+ cc::Layer** end_layer, |
+ cc::SelectionHandle* end_handle) { |
+ DCHECK(start_layer); |
+ DCHECK(end_layer); |
+ if (selection.type == WebSelection::TypeNone) |
+ return false; |
+ |
+ if (!selection.anchorLayer) |
+ return false; |
+ |
+ if (selection.type == WebSelection::TypeInsertion) { |
+ *start_layer = static_cast<const webkit::WebLayerImpl*>( |
+ selection.anchorLayer)->layer(); |
+ start_handle->type = cc::SelectionHandle::CENTER; |
+ start_handle->bounds = gfx::Rect(selection.anchorRectInLayer); |
+ return true; |
+ } |
+ |
+ if (!selection.focusLayer) |
+ return false; |
+ |
+ *start_layer = |
+ static_cast<const webkit::WebLayerImpl*>(selection.anchorLayer)->layer(); |
+ *end_layer = |
+ static_cast<const webkit::WebLayerImpl*>(selection.focusLayer)->layer(); |
+ |
+ // TODO(jdduke): Use text direction (selection.startDirection) and |
+ // anchorIsFirst to properly orient. |
+ start_handle->type = cc::SelectionHandle::LEFT; |
+ end_handle->type = cc::SelectionHandle::RIGHT; |
+ |
+ start_handle->bounds = gfx::Rect(selection.anchorRectInLayer); |
+ end_handle->bounds = gfx::Rect(selection.focusRectInLayer); |
+ |
+ return true; |
+} |
+ |
} // namespace |
// static |
@@ -324,6 +367,7 @@ RenderWidgetCompositor::RenderWidgetCompositor(RenderWidget* widget, |
bool threaded) |
: threaded_(threaded), |
suppress_schedule_composite_(false), |
+ suppress_selection_updates_(false), |
widget_(widget) { |
} |
@@ -426,6 +470,22 @@ bool RenderWidgetCompositor::SendMessageToMicroBenchmark( |
return layer_tree_host_->SendMessageToMicroBenchmark(id, value.Pass()); |
} |
+void RenderWidgetCompositor::SetIgnoreSelectionUpdates(bool ignore_selection) { |
+ if (suppress_selection_updates_ == ignore_selection) |
+ return; |
+ |
+ if (!suppress_selection_updates_) { |
+ cc::SelectionHandle ignored_selection; |
+ ignored_selection.type = cc::SelectionHandle::IGNORED; |
+ layer_tree_host_->RegisterSelection(scoped_refptr<cc::Layer>(), |
+ ignored_selection, |
+ scoped_refptr<cc::Layer>(), |
+ ignored_selection); |
+ } |
+ |
+ suppress_selection_updates_ = ignore_selection; |
+} |
+ |
void RenderWidgetCompositor::Initialize(cc::LayerTreeSettings settings) { |
scoped_refptr<base::MessageLoopProxy> compositor_message_loop_proxy; |
RenderThreadImpl* render_thread = RenderThreadImpl::current(); |
@@ -571,6 +631,37 @@ void RenderWidgetCompositor::clearViewportLayers() { |
scoped_refptr<cc::Layer>()); |
} |
+void RenderWidgetCompositor::registerSelection( |
+ const blink::WebSelection& selection) { |
+ if (suppress_selection_updates_) |
+ return; |
+ |
+ cc::Layer* start_layer = NULL; |
+ cc::SelectionHandle start_handle; |
+ cc::Layer* end_layer = NULL; |
+ cc::SelectionHandle end_handle; |
+ if (!ConvertWebSelection( |
+ selection, &start_layer, &start_handle, &end_layer, &end_handle)) { |
+ clearSelection(); |
+ return; |
+ } |
+ |
+ layer_tree_host_->RegisterSelection( |
+ start_layer, start_handle, end_layer, end_handle); |
+} |
+ |
+void RenderWidgetCompositor::clearSelection() { |
+ if (suppress_selection_updates_) |
+ return; |
+ |
+ cc::SelectionHandle empty_handle; |
+ empty_handle.type = cc::SelectionHandle::NONE; |
+ layer_tree_host_->RegisterSelection(scoped_refptr<cc::Layer>(), |
+ empty_handle, |
+ scoped_refptr<cc::Layer>(), |
+ empty_handle); |
+} |
+ |
void CompositeAndReadbackAsyncCallback( |
blink::WebCompositeAndReadbackAsyncCallback* callback, |
scoped_ptr<cc::CopyOutputResult> result) { |