summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/browser_resources.grd2
-rwxr-xr-xchrome/browser/extensions/extension_view.cc8
-rw-r--r--chrome/browser/renderer_host/render_widget_host_unittest.cc53
-rw-r--r--chrome/browser/renderer_host/render_widget_host_view.h18
-rw-r--r--chrome/browser/renderer_host/render_widget_host_view_win.cc43
-rw-r--r--chrome/browser/renderer_host/render_widget_host_view_win.h6
-rwxr-xr-xchrome/browser/resources/extensions_toolstrip.css17
-rw-r--r--chrome/browser/views/bookmark_bar_view.cc71
-rw-r--r--chrome/browser/views/bookmark_bar_view.h8
-rw-r--r--chrome/browser/views/hwnd_html_view.cc13
-rw-r--r--chrome/browser/views/hwnd_html_view.h8
-rw-r--r--chrome/common/render_messages_internal.h5
-rw-r--r--chrome/common/temp_scaffolding_stubs.h1
-rw-r--r--chrome/renderer/render_view.cc8
-rw-r--r--chrome/renderer/render_view.h6
-rw-r--r--chrome/renderer/render_widget.cc26
-rw-r--r--chrome/renderer/render_widget.h9
-rw-r--r--webkit/glue/webframe_impl.cc3
-rw-r--r--webkit/glue/webview.h5
-rw-r--r--webkit/glue/webview_impl.cc11
-rw-r--r--webkit/glue/webview_impl.h6
21 files changed, 293 insertions, 34 deletions
diff --git a/chrome/browser/browser_resources.grd b/chrome/browser/browser_resources.grd
index 60f9cb5..8ca4fd0 100644
--- a/chrome/browser/browser_resources.grd
+++ b/chrome/browser/browser_resources.grd
@@ -1,4 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- This comment is only here because changes to resources are not picked up
+without changes to the corresponding grd file. -->
<grit latest_public_release="0" current_release="1">
<outputs>
<output filename="grit/browser_resources.h" type="rc_header">
diff --git a/chrome/browser/extensions/extension_view.cc b/chrome/browser/extensions/extension_view.cc
index 05d310e..b55c3aa 100755
--- a/chrome/browser/extensions/extension_view.cc
+++ b/chrome/browser/extensions/extension_view.cc
@@ -35,17 +35,13 @@ ExtensionView::ExtensionView(Extension* extension,
: HWNDHtmlView(url, this, false, instance),
extension_(extension),
browser_(browser) {
- // Set the width initially to 0, so that the WebCore::Document can
- // correctly compute the minPrefWidth which is returned in
- // DidContentsChangeSize()
- set_preferred_size(gfx::Size(0, 100));
SetVisible(false);
}
void ExtensionView::DidStopLoading(RenderViewHost* render_view_host,
int32 page_id) {
- SetVisible(true);
render_view_host->WasResized();
+ SetVisible(true);
}
void ExtensionView::DidContentsPreferredWidthChange(const int pref_width) {
@@ -53,7 +49,7 @@ void ExtensionView::DidContentsPreferredWidthChange(const int pref_width) {
// SchedulePaint first because new_width may be smaller and we want
// the Parent to paint the vacated space.
SchedulePaint();
- set_preferred_size(gfx::Size(pref_width, 100));
+ set_preferred_size(gfx::Size(pref_width, height()));
SizeToPreferredSize();
// TODO(rafaelw): This assumes that the extension view is a child of an
diff --git a/chrome/browser/renderer_host/render_widget_host_unittest.cc b/chrome/browser/renderer_host/render_widget_host_unittest.cc
index 0711e3d..cea36c9 100644
--- a/chrome/browser/renderer_host/render_widget_host_unittest.cc
+++ b/chrome/browser/renderer_host/render_widget_host_unittest.cc
@@ -9,6 +9,7 @@
#include "build/build_config.h"
#include "chrome/browser/renderer_host/backing_store.h"
#include "chrome/browser/renderer_host/test_render_view_host.h"
+#include "chrome/common/gfx/chrome_canvas.h"
#include "chrome/common/render_messages.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -244,6 +245,58 @@ TEST_F(RenderWidgetHostTest, Resize) {
EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID));
}
+// Tests setting custom background
+TEST_F(RenderWidgetHostTest, Background) {
+#if defined(OS_WIN) || defined(OS_LINUX)
+ scoped_ptr<RenderWidgetHostView> view(
+ RenderWidgetHostView::CreateViewForWidget(host_.get()));
+ host_->set_view(view.get());
+
+ // Create a checkerboard background to test with.
+ ChromeCanvas canvas(4, 4, true);
+ canvas.FillRectInt(SK_ColorBLACK, 0, 0, 2, 2);
+ canvas.FillRectInt(SK_ColorWHITE, 2, 0, 2, 2);
+ canvas.FillRectInt(SK_ColorWHITE, 0, 2, 2, 2);
+ canvas.FillRectInt(SK_ColorBLACK, 2, 2, 2, 2);
+ const SkBitmap& background = canvas.getDevice()->accessBitmap(false);
+
+ // Set the background and make sure we get back a copy.
+ view->SetBackground(background);
+ EXPECT_EQ(4, view->background().width());
+ EXPECT_EQ(4, view->background().height());
+ EXPECT_EQ(background.getSize(), view->background().getSize());
+ EXPECT_TRUE(0 == memcmp(background.getPixels(),
+ view->background().getPixels(),
+ background.getSize()));
+
+#if defined(OS_WIN)
+ // A message should have been dispatched telling the renderer about the new
+ // background.
+ const IPC::Message* set_background =
+ process_->sink().GetUniqueMessageMatching(ViewMsg_SetBackground::ID);
+ ASSERT_TRUE(set_background);
+ SkBitmap sent_background;
+ ViewMsg_SetBackground::Read(set_background, &sent_background);
+ EXPECT_EQ(background.getSize(), sent_background.getSize());
+ EXPECT_TRUE(0 == memcmp(background.getPixels(),
+ sent_background.getPixels(),
+ background.getSize()));
+#else
+ // TODO(port): When custom backgrounds are implemented for other ports, this
+ // test should work (assuming the background must still be copied into the
+ // renderer -- if not, then maybe the test doesn't apply?).
+#endif
+
+#else
+ // TODO(port): Mac does not have ChromeCanvas. Maybe we can just change this
+ // test to use SkCanvas directly?
+#endif
+
+ // TODO(aa): It would be nice to factor out the painting logic so that we
+ // could test that, but it appears that would mean painting everything twice
+ // since windows HDC structures are opaque.
+}
+
// Tests getting the backing store with the renderer not setting repaint ack
// flags.
TEST_F(RenderWidgetHostTest, GetBackingStore_NoRepaintAck) {
diff --git a/chrome/browser/renderer_host/render_widget_host_view.h b/chrome/browser/renderer_host/render_widget_host_view.h
index db894f8..beec90e 100644
--- a/chrome/browser/renderer_host/render_widget_host_view.h
+++ b/chrome/browser/renderer_host/render_widget_host_view.h
@@ -8,6 +8,7 @@
#include "base/gfx/native_widget_types.h"
#include "base/shared_memory.h"
#include "webkit/glue/webplugin.h"
+#include "skia/include/SkBitmap.h"
namespace gfx {
class Rect;
@@ -31,6 +32,8 @@ class WebCursor;
// changes.
class RenderWidgetHostView {
public:
+ virtual ~RenderWidgetHostView(){};
+
// Platform-specific creator. Use this to construct new RenderWidgetHostViews
// rather than using RenderWidgetHostViewWin & friends.
//
@@ -138,14 +141,25 @@ class RenderWidgetHostView {
}
bool activatable() const { return activatable_; }
+ // Subclasses should override this method to do whatever is appropriate to set
+ // the custom background for their platform.
+ virtual void SetBackground(const SkBitmap& background) {
+ background_ = background;
+ }
+ const SkBitmap& background() const { return background_; }
+
protected:
// Interface class only, do not construct.
- RenderWidgetHostView() : activatable_(true) {}
-
+ RenderWidgetHostView() : activatable_(true) {}
+
// Whether the window can be activated. Autocomplete popup windows for example
// cannot be activated. Default is true.
bool activatable_;
+ // A custom background to paint behind the web content. This will be tiled
+ // horizontally. Can be null, in which case we fall back to painting white.
+ SkBitmap background_;
+
private:
DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostView);
};
diff --git a/chrome/browser/renderer_host/render_widget_host_view_win.cc b/chrome/browser/renderer_host/render_widget_host_view_win.cc
index 58fbc83..d13fac4 100644
--- a/chrome/browser/renderer_host/render_widget_host_view_win.cc
+++ b/chrome/browser/renderer_host/render_widget_host_view_win.cc
@@ -31,6 +31,7 @@
// Included for views::kReflectedMessage - TODO(beng): move this to win_util.h!
#include "chrome/views/widget/widget_win.h"
#include "grit/webkit_resources.h"
+#include "skia/ext/skia_utils_win.h"
#include "third_party/WebKit/WebKit/chromium/public/WebInputEvent.h"
#include "third_party/WebKit/WebKit/chromium/public/win/WebInputEventFactory.h"
#include "webkit/glue/plugins/plugin_constants_win.h"
@@ -641,6 +642,12 @@ BackingStore* RenderWidgetHostViewWin::AllocBackingStore(
return new BackingStore(size);
}
+void RenderWidgetHostViewWin::SetBackground(const SkBitmap& background) {
+ RenderWidgetHostView::SetBackground(background);
+ Send(new ViewMsg_SetBackground(render_widget_host_->routing_id(),
+ background));
+}
+
///////////////////////////////////////////////////////////////////////////////
// RenderWidgetHostViewWin, private:
@@ -686,10 +693,11 @@ void RenderWidgetHostViewWin::OnPaint(HDC dc) {
about_to_validate_and_paint_ = false;
CPaintDC paint_dc(m_hWnd);
- HBRUSH white_brush = reinterpret_cast<HBRUSH>(GetStockObject(WHITE_BRUSH));
- if (backing_store) {
- gfx::Rect damaged_rect(paint_dc.m_ps.rcPaint);
+ gfx::Rect damaged_rect(paint_dc.m_ps.rcPaint);
+ if (damaged_rect.IsEmpty())
+ return;
+ if (backing_store) {
gfx::Rect bitmap_rect(
0, 0, backing_store->size().width(), backing_store->size().height());
@@ -707,14 +715,14 @@ void RenderWidgetHostViewWin::OnPaint(HDC dc) {
SRCCOPY);
}
- // Fill the remaining portion of the damaged_rect with white
+ // Fill the remaining portion of the damaged_rect with the background
if (damaged_rect.right() > bitmap_rect.right()) {
RECT r;
r.left = std::max(bitmap_rect.right(), damaged_rect.x());
r.right = damaged_rect.right();
r.top = damaged_rect.y();
r.bottom = std::min(bitmap_rect.bottom(), damaged_rect.bottom());
- paint_dc.FillRect(&r, white_brush);
+ DrawBackground(r, &paint_dc);
}
if (damaged_rect.bottom() > bitmap_rect.bottom()) {
RECT r;
@@ -722,7 +730,7 @@ void RenderWidgetHostViewWin::OnPaint(HDC dc) {
r.right = damaged_rect.right();
r.top = std::max(bitmap_rect.bottom(), damaged_rect.y());
r.bottom = damaged_rect.bottom();
- paint_dc.FillRect(&r, white_brush);
+ DrawBackground(r, &paint_dc);
}
if (!whiteout_start_time_.is_null()) {
TimeDelta whiteout_duration = TimeTicks::Now() - whiteout_start_time_;
@@ -733,12 +741,33 @@ void RenderWidgetHostViewWin::OnPaint(HDC dc) {
whiteout_start_time_ = TimeTicks();
}
} else {
- paint_dc.FillRect(&paint_dc.m_ps.rcPaint, white_brush);
+ DrawBackground(paint_dc.m_ps.rcPaint, &paint_dc);
if (whiteout_start_time_.is_null())
whiteout_start_time_ = TimeTicks::Now();
}
}
+void RenderWidgetHostViewWin::DrawBackground(const RECT& dirty_rect,
+ CPaintDC* dc) {
+ const RECT& dc_rect = dc->m_ps.rcPaint;
+ if (!background_.empty()) {
+ ChromeCanvas canvas(dirty_rect.right - dirty_rect.left,
+ dirty_rect.bottom - dirty_rect.top,
+ true); // opaque
+
+ canvas.TranslateInt(-dirty_rect.left, -dirty_rect.top);
+ canvas.TileImageInt(background_, 0, 0,
+ dc_rect.right - dc_rect.left,
+ dc_rect.bottom - dc_rect.top);
+
+ canvas.getTopPlatformDevice().drawToHDC(*dc, dirty_rect.left,
+ dirty_rect.top, NULL);
+ } else {
+ HBRUSH white_brush = reinterpret_cast<HBRUSH>(GetStockObject(WHITE_BRUSH));
+ dc->FillRect(&dc_rect, white_brush);
+ }
+}
+
void RenderWidgetHostViewWin::OnNCPaint(HRGN update_region) {
// Do nothing. This suppresses the resize corner that Windows would
// otherwise draw for us.
diff --git a/chrome/browser/renderer_host/render_widget_host_view_win.h b/chrome/browser/renderer_host/render_widget_host_view_win.h
index 3501ca1..5b80f09 100644
--- a/chrome/browser/renderer_host/render_widget_host_view_win.h
+++ b/chrome/browser/renderer_host/render_widget_host_view_win.h
@@ -130,6 +130,7 @@ class RenderWidgetHostViewWin :
virtual void Destroy();
virtual void SetTooltipText(const std::wstring& tooltip_text);
virtual BackingStore* AllocBackingStore(const gfx::Size& size);
+ virtual void SetBackground(const SkBitmap& background);
protected:
// Windows Message Handlers
@@ -210,6 +211,11 @@ class RenderWidgetHostViewWin :
// given paint rect.
void DrawResizeCorner(const gfx::Rect& paint_rect, HDC dc);
+ // Draw our background over the given HDC in the given |rect|. The background
+ // will be tiled such that it lines up with existing tiles starting from the
+ // origin of |dc|.
+ void DrawBackground(const RECT& rect, CPaintDC* dc);
+
// Create an intermediate window between the given HWND and its parent.
HWND ReparentWindow(HWND window);
diff --git a/chrome/browser/resources/extensions_toolstrip.css b/chrome/browser/resources/extensions_toolstrip.css
index 921f97f..b709856 100755
--- a/chrome/browser/resources/extensions_toolstrip.css
+++ b/chrome/browser/resources/extensions_toolstrip.css
@@ -1,16 +1,13 @@
body {
+ display:-webkit-box;
+ -webkit-box-align:center;
+ white-space:nowrap;
overflow: hidden;
margin: 0;
- padding: 0;
+ padding:0 6px;
font: menu;
- text-shadow: #FFFFFF 1px 1px 0px;
color: #062D75;
-}
-
-#main {
- background: -webkit-gradient(linear, left top, left bottom, from(rgb(222, 234, 248)), to(rgb(237, 244, 252)));
- padding-top: 3px;
- height: 21px;
- overflow: hidden;
- white-space: nowrap;
+ text-shadow: #FFFFFF 1px 1px 0px;
+ -webkit-user-select:none;
+ cursor:default;
}
diff --git a/chrome/browser/views/bookmark_bar_view.cc b/chrome/browser/views/bookmark_bar_view.cc
index b0be7dd..b5298db 100644
--- a/chrome/browser/views/bookmark_bar_view.cc
+++ b/chrome/browser/views/bookmark_bar_view.cc
@@ -17,6 +17,8 @@
#include "chrome/browser/extensions/extensions_service.h"
#include "chrome/browser/metrics/user_metrics.h"
#include "chrome/browser/profile.h"
+#include "chrome/browser/renderer_host/render_view_host.h"
+#include "chrome/browser/renderer_host/render_widget_host_view.h"
#include "chrome/browser/tab_contents/page_navigator.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/browser/view_ids.h"
@@ -297,20 +299,16 @@ class BookmarkFolderButton : public views::MenuButton {
// A simple container with a border for an ExtensionView.
class ExtensionToolstrip : public views::View {
public:
- static const int kPadding = 2;
-
ExtensionToolstrip(Extension* extension, const GURL& url, Browser* browser)
: view_(browser->profile()->GetExtensionsService()->CreateView(
extension, url, browser)) {
AddChildView(view_);
- set_border(views::Border::CreateEmptyBorder(
- kPadding, kPadding, kPadding, kPadding));
}
+ ExtensionView* view() { return view_; }
+
virtual gfx::Size GetPreferredSize() {
- gfx::Size size = view_->GetPreferredSize();
- size.Enlarge(kPadding*2, kPadding*2);
- return size;
+ return view_->GetPreferredSize();
}
virtual void DidChangeBounds(const gfx::Rect& previous,
@@ -689,6 +687,13 @@ void BookmarkBarView::Paint(ChromeCanvas* canvas) {
canvas->drawRoundRect(rect,
SkDoubleToScalar(roundness),
SkDoubleToScalar(roundness), border_paint);
+
+ SkRect toolstrip_background_rect = {
+ rect.fLeft + 1 + kNewtabBarRoundness,
+ rect.fTop + 1,
+ rect.fLeft + 1 + kNewtabBarRoundness + 1,
+ rect.fBottom - 1};
+ InitToolstripBackground(canvas, toolstrip_background_rect);
} else {
SkPaint paint;
paint.setShader(skia::CreateGradientShader(0,
@@ -699,6 +704,51 @@ void BookmarkBarView::Paint(ChromeCanvas* canvas) {
canvas->FillRectInt(kTopBorderColor, 0, 0, width(), 1);
canvas->FillRectInt(kBottomBorderColor, 0, height() - 1, width(), 1);
+
+ SkRect toolstrip_background_rect = {
+ SkIntToScalar(0),
+ SkIntToScalar(1),
+ SkIntToScalar(1),
+ SkIntToScalar(height() - 2)};
+ InitToolstripBackground(canvas, toolstrip_background_rect);
+ }
+}
+
+void BookmarkBarView::InitToolstripBackground(ChromeCanvas* canvas,
+ const SkRect& subset) {
+ if (!toolstrip_background_.empty())
+ return;
+
+ const SkBitmap& bookmarkbar_background =
+ canvas->getDevice()->accessBitmap(false);
+
+ // Extract the correct subset of the toolstrip background into a bitmap. We
+ // must use a temporary here because extractSubset() returns a bitmap that
+ // references pixels in the original one and we want to actually make a copy
+ // that will have a long lifetime.
+ SkBitmap temp;
+ temp.setConfig(bookmarkbar_background.config(),
+ static_cast<int>(subset.width()),
+ static_cast<int>(subset.height()));
+
+ SkRect mapped_subset = subset;
+ bool result = canvas->getTotalMatrix().mapRect(&mapped_subset);
+ DCHECK(result);
+
+ SkIRect isubset;
+ mapped_subset.round(&isubset);
+ result = bookmarkbar_background.extractSubset(&temp, isubset);
+ if (!result)
+ return;
+
+ temp.copyTo(&toolstrip_background_, temp.config());
+ DCHECK(toolstrip_background_.readyToDraw());
+
+ // Tell all current toolstrips about the new background
+ for (int i = GetBookmarkButtonCount();
+ i < GetBookmarkButtonCount() + num_extension_toolstrips_; ++i) {
+ static_cast<ExtensionToolstrip*>(GetChildViewAt(i))->view()->SetBackground(
+ toolstrip_background_);
}
}
@@ -898,11 +948,17 @@ int BookmarkBarView::GetToolbarOverlap() {
void BookmarkBarView::AnimationProgressed(const Animation* animation) {
if (browser_)
browser_->ToolbarSizeChanged(true);
+
+ // Clear the toolstrip background so that we recreate it next time around the
+ // paint loop.
+ toolstrip_background_.reset();
}
void BookmarkBarView::AnimationEnded(const Animation* animation) {
if (browser_)
browser_->ToolbarSizeChanged(false);
+
+ toolstrip_background_.reset();
SchedulePaint();
}
@@ -1379,6 +1435,7 @@ bool BookmarkBarView::AddExtensionToolstrips(const ExtensionList* extensions) {
(*extension)->GetResourceURL(*toolstrip),
browser_);
int index = GetBookmarkButtonCount() + num_extension_toolstrips_;
+ view->view()->SetBackground(toolstrip_background_);
AddChildView(index, view);
added_toolstrip = true;
++num_extension_toolstrips_;
diff --git a/chrome/browser/views/bookmark_bar_view.h b/chrome/browser/views/bookmark_bar_view.h
index 0726449..3963326 100644
--- a/chrome/browser/views/bookmark_bar_view.h
+++ b/chrome/browser/views/bookmark_bar_view.h
@@ -15,6 +15,7 @@
#include "chrome/views/controls/menu/menu.h"
#include "chrome/views/controls/menu/view_menu_delegate.h"
#include "chrome/views/view.h"
+#include "skia/include/corecg/SkRect.h"
class Browser;
class PageNavigator;
@@ -375,6 +376,10 @@ class BookmarkBarView : public views::View,
// button. Returns true if there were any new toolstrips added.
bool AddExtensionToolstrips(const ExtensionList* extensions);
+ // Initializes the bitmap we use for the background of extension toolstrips by
+ // copying a subset of the current toolstrip background.
+ void InitToolstripBackground(ChromeCanvas* canvas, const SkRect& subset);
+
Profile* profile_;
// Used for opening urls.
@@ -430,6 +435,9 @@ class BookmarkBarView : public views::View,
// How many extension toolstrips we have showing in the toolbar.
int num_extension_toolstrips_;
+ // Background for extension toolstrips.
+ SkBitmap toolstrip_background_;
+
DISALLOW_COPY_AND_ASSIGN(BookmarkBarView);
};
diff --git a/chrome/browser/views/hwnd_html_view.cc b/chrome/browser/views/hwnd_html_view.cc
index 9eb8cc4..a0174d6 100644
--- a/chrome/browser/views/hwnd_html_view.cc
+++ b/chrome/browser/views/hwnd_html_view.cc
@@ -32,6 +32,15 @@ HWNDHtmlView::~HWNDHtmlView() {
}
}
+void HWNDHtmlView::SetBackground(const SkBitmap& background) {
+ if (initialized_) {
+ DCHECK(render_view_host_);
+ render_view_host_->view()->SetBackground(background);
+ } else {
+ pending_background_ = background;
+ }
+}
+
void HWNDHtmlView::InitHidden() {
// TODO(mpcomplete): make it possible to create a RenderView without an HWND.
views::WidgetWin* win = new views::WidgetWin;
@@ -62,6 +71,10 @@ void HWNDHtmlView::Init(HWND parent_hwnd) {
rvh->AllowDOMUIBindings();
CreatingRenderer();
rvh->CreateRenderView();
+ if (!pending_background_.empty()) {
+ rvh->view()->SetBackground(pending_background_);
+ pending_background_.reset();
+ }
rvh->NavigateToURL(content_url_);
initialized_ = true;
}
diff --git a/chrome/browser/views/hwnd_html_view.h b/chrome/browser/views/hwnd_html_view.h
index 3176551..49e2c88 100644
--- a/chrome/browser/views/hwnd_html_view.h
+++ b/chrome/browser/views/hwnd_html_view.h
@@ -7,6 +7,7 @@
#include "googleurl/src/gurl.h"
#include "chrome/views/controls/hwnd_view.h"
+#include "skia/include/SkBitmap.h"
class RenderViewHost;
class RenderViewHostDelegate;
@@ -27,6 +28,9 @@ class HWNDHtmlView : public views::HWNDView {
// don't display UI.
void InitHidden();
+ // Set a custom background for the view. The background will be tiled.
+ void SetBackground(const SkBitmap& background);
+
protected:
// View overrides.
virtual void ViewHierarchyChanged(bool is_add, View *parent, View *child);
@@ -60,6 +64,10 @@ class HWNDHtmlView : public views::HWNDView {
// The delegate for our render_view_host.
RenderViewHostDelegate* delegate_;
+ // The background the view should have once it is initialized. This is set
+ // when the view has a custom background, but hasn't been inititalized yet.
+ SkBitmap pending_background_;
+
DISALLOW_EVIL_CONSTRUCTORS(HWNDHtmlView);
};
diff --git a/chrome/common/render_messages_internal.h b/chrome/common/render_messages_internal.h
index 2fdf5a9..e254c4f 100644
--- a/chrome/common/render_messages_internal.h
+++ b/chrome/common/render_messages_internal.h
@@ -571,6 +571,11 @@ IPC_BEGIN_MESSAGES(View)
// Tells the renderer to clear the focused node (if any).
IPC_MESSAGE_ROUTED0(ViewMsg_ClearFocusedNode)
+
+ // Make the RenderView transparent and render it onto a custom background. The
+ // background will be tiled in both directions if it is not large enough.
+ IPC_MESSAGE_ROUTED1(ViewMsg_SetBackground,
+ SkBitmap /* background */)
IPC_END_MESSAGES(View)
diff --git a/chrome/common/temp_scaffolding_stubs.h b/chrome/common/temp_scaffolding_stubs.h
index cac23ea..93a3b7d 100644
--- a/chrome/common/temp_scaffolding_stubs.h
+++ b/chrome/common/temp_scaffolding_stubs.h
@@ -505,6 +505,7 @@ class HWNDHtmlView {
}
virtual ~HWNDHtmlView() {}
+ int height() { NOTIMPLEMENTED(); return 0; }
RenderViewHost* render_view_host() { NOTIMPLEMENTED(); return NULL; }
void InitHidden() { NOTIMPLEMENTED(); }
void set_preferred_size(const gfx::Size& size) { NOTIMPLEMENTED(); }
diff --git a/chrome/renderer/render_view.cc b/chrome/renderer/render_view.cc
index 1893e25..e3cbc9f 100644
--- a/chrome/renderer/render_view.cc
+++ b/chrome/renderer/render_view.cc
@@ -443,6 +443,7 @@ void RenderView::OnMessageReceived(const IPC::Message& message) {
IPC_MESSAGE_HANDLER(ViewMsg_MoveOrResizeStarted, OnMoveOrResizeStarted)
IPC_MESSAGE_HANDLER(ViewMsg_ExtensionResponse, OnExtensionResponse)
IPC_MESSAGE_HANDLER(ViewMsg_ClearFocusedNode, OnClearFocusedNode)
+ IPC_MESSAGE_HANDLER(ViewMsg_SetBackground, OnSetBackground)
// Have the super handle all other messages.
IPC_MESSAGE_UNHANDLED(RenderWidget::OnMessageReceived(message))
@@ -2954,6 +2955,13 @@ void RenderView::OnClearFocusedNode() {
webview()->ClearFocusedNode();
}
+void RenderView::OnSetBackground(const SkBitmap& background) {
+ if (webview())
+ webview()->SetIsTransparent(!background.empty());
+
+ SetBackground(background);
+}
+
void RenderView::SendExtensionRequest(const std::string& name,
const std::string& args,
int callback_id,
diff --git a/chrome/renderer/render_view.h b/chrome/renderer/render_view.h
index eb3aa55..505dca0 100644
--- a/chrome/renderer/render_view.h
+++ b/chrome/renderer/render_view.h
@@ -26,6 +26,7 @@
#include "chrome/renderer/external_host_bindings.h"
#include "chrome/renderer/external_js_object.h"
#include "chrome/renderer/render_widget.h"
+#include "skia/include/SkBitmap.h"
#include "testing/gtest/include/gtest/gtest_prod.h"
#include "third_party/WebKit/WebKit/chromium/public/WebConsoleMessage.h"
#include "webkit/glue/dom_serializer_delegate.h"
@@ -52,7 +53,6 @@ class FilePath;
class GURL;
class RenderThread;
class ResourceDispatcher;
-class SkBitmap;
class WebAccessibilityManager;
class WebError;
class WebFrame;
@@ -582,6 +582,10 @@ class RenderView : public RenderWidget,
// Sends the selection text to the browser.
void OnRequestSelectionText();
+ // Handle message to make the RenderView transparent and render it on top of
+ // a custom background.
+ void OnSetBackground(const SkBitmap& background);
+
// Prints the page listed in |params|.
void PrintPage(const ViewMsg_PrintPage_Params& params,
const gfx::Size& canvas_size,
diff --git a/chrome/renderer/render_widget.cc b/chrome/renderer/render_widget.cc
index 4cd54c1..23f27da 100644
--- a/chrome/renderer/render_widget.cc
+++ b/chrome/renderer/render_widget.cc
@@ -14,6 +14,7 @@
#include "chrome/common/transport_dib.h"
#include "chrome/renderer/render_process.h"
#include "skia/ext/platform_canvas.h"
+#include "skia/include/SkShader.h"
#include "third_party/WebKit/WebKit/chromium/public/WebRect.h"
#include "third_party/WebKit/WebKit/chromium/public/WebScreenInfo.h"
#include "third_party/WebKit/WebKit/chromium/public/WebSize.h"
@@ -308,6 +309,25 @@ void RenderWidget::ClearFocus() {
void RenderWidget::PaintRect(const gfx::Rect& rect,
skia::PlatformCanvas* canvas) {
+
+ // If there is a custom background, tile it.
+ if (!background_.empty()) {
+ canvas->save();
+
+ SkIRect clipRect = { rect.x(), rect.y(), rect.right(), rect.bottom() };
+ canvas->setClipRegion(SkRegion(clipRect));
+
+ SkPaint paint;
+ SkShader* shader = SkShader::CreateBitmapShader(background_,
+ SkShader::kRepeat_TileMode,
+ SkShader::kRepeat_TileMode);
+ paint.setShader(shader)->unref();
+ paint.setPorterDuffXfermode(SkPorterDuff::kSrcOver_Mode);
+ canvas->drawPaint(paint);
+
+ canvas->restore();
+ }
+
// Bring the canvas into the coordinate system of the paint rect
canvas->translate(static_cast<SkScalar>(-rect.x()),
static_cast<SkScalar>(-rect.y()));
@@ -675,6 +695,12 @@ void RenderWidget::OnSetTextDirection(int direction) {
}
}
+void RenderWidget::SetBackground(const SkBitmap& background) {
+ background_ = background;
+ // Generate a full repaint.
+ DidInvalidateRect(webwidget_, gfx::Rect(size_.width(), size_.height()));
+}
+
bool RenderWidget::next_paint_is_resize_ack() const {
return ViewHostMsg_PaintRect_Flags::is_resize_ack(next_paint_flags_);
}
diff --git a/chrome/renderer/render_widget.h b/chrome/renderer/render_widget.h
index 668b4fd..62777e8 100644
--- a/chrome/renderer/render_widget.h
+++ b/chrome/renderer/render_widget.h
@@ -16,6 +16,7 @@
#include "chrome/common/ipc_channel.h"
#include "chrome/renderer/render_process.h"
#include "skia/ext/platform_canvas.h"
+#include "skia/include/SkBitmap.h"
#include "webkit/glue/webwidget_delegate.h"
#include "webkit/glue/webcursor.h"
@@ -123,6 +124,11 @@ class RenderWidget : public IPC::Channel::Listener,
// corresponding paint or scroll message is send to the widget host.
virtual void DidPaint() {}
+ // Set the background of the render widget to a bitmap. The bitmap will be
+ // tiled in both directions if it isn't big enough to fill the area. This is
+ // mainly intended to be used in conjuction with WebView::SetIsTransparent().
+ virtual void SetBackground(const SkBitmap& bitmap);
+
// RenderWidget IPC message handlers
void OnClose();
void OnCreatingNewAck(gfx::NativeViewId parent);
@@ -271,6 +277,9 @@ class RenderWidget : public IPC::Channel::Listener,
// Holds all the needed plugin window moves for a scroll.
std::vector<WebPluginGeometry> plugin_window_moves_;
+ // A custom background for the widget.
+ SkBitmap background_;
+
DISALLOW_COPY_AND_ASSIGN(RenderWidget);
};
diff --git a/webkit/glue/webframe_impl.cc b/webkit/glue/webframe_impl.cc
index 6c55b48..1d21d0a 100644
--- a/webkit/glue/webframe_impl.cc
+++ b/webkit/glue/webframe_impl.cc
@@ -1532,6 +1532,9 @@ void WebFrameImpl::CreateFrameView() {
frame_->setView(view);
+ if (webview_impl_->GetIsTransparent())
+ view->setTransparent(true);
+
// TODO(darin): The Mac code has a comment about this possibly being
// unnecessary. See installInFrame in WebCoreFrameBridge.mm
if (frame_->ownerRenderer())
diff --git a/webkit/glue/webview.h b/webkit/glue/webview.h
index 600338f..2a9faec 100644
--- a/webkit/glue/webview.h
+++ b/webkit/glue/webview.h
@@ -226,6 +226,11 @@ class WebView : public WebWidget {
// Returns development tools agent instance belonging to this view.
virtual WebDevToolsAgent* GetWebDevToolsAgent() = 0;
+ // Makes the webview transparent. Useful if you want to have some custom
+ // background behind it.
+ virtual void SetIsTransparent(bool is_transparent) = 0;
+ virtual bool GetIsTransparent() const = 0;
+
private:
DISALLOW_COPY_AND_ASSIGN(WebView);
};
diff --git a/webkit/glue/webview_impl.cc b/webkit/glue/webview_impl.cc
index 9906a27..0155b8b 100644
--- a/webkit/glue/webview_impl.cc
+++ b/webkit/glue/webview_impl.cc
@@ -366,7 +366,8 @@ WebViewImpl::WebViewImpl()
drag_identity_(0),
drop_effect_(DROP_EFFECT_DEFAULT),
drop_accept_(false),
- autocomplete_popup_showing_(false) {
+ autocomplete_popup_showing_(false),
+ is_transparent_(false) {
// WebKit/win/WebView.cpp does the same thing, except they call the
// KJS specific wrapper around this method. We need to have threading
// initialized because CollatorICU requires it.
@@ -1825,6 +1826,14 @@ WebDevToolsAgentImpl* WebViewImpl::GetWebDevToolsAgentImpl() {
return devtools_agent_.get();
}
+void WebViewImpl::SetIsTransparent(bool is_transparent) {
+ is_transparent_ = is_transparent;
+}
+
+bool WebViewImpl::GetIsTransparent() const {
+ return is_transparent_;
+}
+
void WebViewImpl::DidCommitLoad(bool* is_new_navigation) {
if (is_new_navigation)
*is_new_navigation = observed_new_navigation_;
diff --git a/webkit/glue/webview_impl.h b/webkit/glue/webview_impl.h
index 71a5a86..0b8db72 100644
--- a/webkit/glue/webview_impl.h
+++ b/webkit/glue/webview_impl.h
@@ -125,6 +125,9 @@ class WebViewImpl : public WebView, public base::RefCounted<WebViewImpl> {
virtual WebDevToolsAgent* GetWebDevToolsAgent();
WebDevToolsAgentImpl* GetWebDevToolsAgentImpl();
+ virtual void SetIsTransparent(bool is_transparent);
+ virtual bool GetIsTransparent() const;
+
// WebViewImpl
const WebKit::WebSize& size() const { return size_; }
@@ -351,6 +354,9 @@ class WebViewImpl : public WebView, public base::RefCounted<WebViewImpl> {
scoped_ptr<WebDevToolsAgentImpl> devtools_agent_;
+ // Whether the webview is rendering transparently.
+ bool is_transparent_;
+
// HACK: current_input_event is for ChromeClientImpl::show(), until we can fix
// WebKit to pass enough information up into ChromeClient::show() so we can
// decide if the window.open event was caused by a middle-mouse click