diff options
-rw-r--r-- | chrome/browser/gtk/constrained_window_gtk.cc | 14 | ||||
-rw-r--r-- | chrome/browser/gtk/constrained_window_gtk.h | 16 | ||||
-rw-r--r-- | chrome/browser/renderer_host/backing_store_x.cc | 5 | ||||
-rw-r--r-- | chrome/browser/renderer_host/backing_store_x.h | 10 | ||||
-rw-r--r-- | chrome/browser/renderer_host/render_widget_host_view_gtk.cc | 2 | ||||
-rw-r--r-- | chrome/browser/renderer_host/render_widget_host_view_views.cc | 26 | ||||
-rw-r--r-- | chrome/browser/ui/views/tab_contents/tab_contents_container.cc | 40 | ||||
-rw-r--r-- | chrome/browser/ui/views/tab_contents/tab_contents_view_views.cc | 299 | ||||
-rw-r--r-- | chrome/browser/ui/views/tab_contents/tab_contents_view_views.h | 128 | ||||
-rw-r--r-- | chrome/chrome_browser.gypi | 26 | ||||
-rw-r--r-- | gfx/canvas.h | 5 | ||||
-rw-r--r-- | gfx/canvas_direct2d.cc | 6 | ||||
-rw-r--r-- | gfx/canvas_direct2d.h | 2 | ||||
-rw-r--r-- | gfx/canvas_skia.cc | 8 | ||||
-rw-r--r-- | gfx/canvas_skia.h | 2 |
15 files changed, 565 insertions, 24 deletions
diff --git a/chrome/browser/gtk/constrained_window_gtk.cc b/chrome/browser/gtk/constrained_window_gtk.cc index f10dc03..195fb17 100644 --- a/chrome/browser/gtk/constrained_window_gtk.cc +++ b/chrome/browser/gtk/constrained_window_gtk.cc @@ -9,7 +9,12 @@ #include "chrome/browser/browser_list.h" #include "chrome/browser/gtk/gtk_util.h" #include "chrome/browser/tab_contents/tab_contents.h" + +#if defined(TOUCH_UI) +#include "chrome/browser/ui/views/tab_contents/tab_contents_view_views.h" +#else #include "chrome/browser/tab_contents/tab_contents_view_gtk.h" +#endif ConstrainedWindowGtkDelegate::~ConstrainedWindowGtkDelegate() { } @@ -66,8 +71,8 @@ ConstrainedWindowGtk::~ConstrainedWindowGtk() { void ConstrainedWindowGtk::ShowConstrainedWindow() { gtk_widget_show_all(border_.get()); - // We collaborate with TabContentsViewGtk and stick ourselves in the - // TabContentsViewGtk's floating container. + // We collaborate with TabContentsView and stick ourselves in the + // TabContentsView's floating container. ContainingView()->AttachConstrainedWindow(this); visible_ = true; @@ -82,8 +87,9 @@ void ConstrainedWindowGtk::CloseConstrainedWindow() { delete this; } -TabContentsViewGtk* ConstrainedWindowGtk::ContainingView() { - return static_cast<TabContentsViewGtk*>(owner_->view()); +ConstrainedWindowGtk::TabContentsViewType* + ConstrainedWindowGtk::ContainingView() { + return static_cast<TabContentsViewType*>(owner_->view()); } gboolean ConstrainedWindowGtk::OnKeyPress(GtkWidget* sender, diff --git a/chrome/browser/gtk/constrained_window_gtk.h b/chrome/browser/gtk/constrained_window_gtk.h index 16b4b33..0f57f65 100644 --- a/chrome/browser/gtk/constrained_window_gtk.h +++ b/chrome/browser/gtk/constrained_window_gtk.h @@ -15,8 +15,12 @@ #include "chrome/browser/tab_contents/constrained_window.h" class TabContents; -class TabContentsViewGtk; typedef struct _GdkColor GdkColor; +#if defined(TOUCH_UI) +class TabContentsViewViews; +#else +class TabContentsViewGtk; +#endif class ConstrainedWindowGtkDelegate { public: @@ -38,6 +42,12 @@ class ConstrainedWindowGtkDelegate { // centers the dialog. It is thus an order of magnitude simpler. class ConstrainedWindowGtk : public ConstrainedWindow { public: +#if defined(TOUCH_UI) + typedef TabContentsViewViews TabContentsViewType; +#else + typedef TabContentsViewGtk TabContentsViewType; +#endif + virtual ~ConstrainedWindowGtk(); // Overridden from ConstrainedWindow: @@ -51,7 +61,7 @@ class ConstrainedWindowGtk : public ConstrainedWindow { GtkWidget* widget() { return border_.get(); } // Returns the View that we collaborate with to position ourselves. - TabContentsViewGtk* ContainingView(); + TabContentsViewType* ContainingView(); private: friend class ConstrainedWindow; @@ -66,7 +76,7 @@ class ConstrainedWindowGtk : public ConstrainedWindow { // The TabContents that owns and constrains this ConstrainedWindow. TabContents* owner_; - // The top level widget container that exports to our TabContentsViewGtk. + // The top level widget container that exports to our TabContentsView. OwnedWidgetGtk border_; // Delegate that provides the contents of this constrained window. diff --git a/chrome/browser/renderer_host/backing_store_x.cc b/chrome/browser/renderer_host/backing_store_x.cc index 9fc7e5c..d71b391 100644 --- a/chrome/browser/renderer_host/backing_store_x.cc +++ b/chrome/browser/renderer_host/backing_store_x.cc @@ -430,10 +430,11 @@ void BackingStoreX::ScrollBackingStore(int dx, int dy, } } -void BackingStoreX::XShowRect(const gfx::Rect& rect, XID target) { +void BackingStoreX::XShowRect(const gfx::Point &origin, + const gfx::Rect& rect, XID target) { XCopyArea(display_, pixmap_, target, static_cast<GC>(pixmap_gc_), rect.x(), rect.y(), rect.width(), rect.height(), - rect.x(), rect.y()); + rect.x() + origin.x(), rect.y() + origin.y()); } void BackingStoreX::CairoShowRect(const gfx::Rect& rect, diff --git a/chrome/browser/renderer_host/backing_store_x.h b/chrome/browser/renderer_host/backing_store_x.h index e6a73a7..fd249b3 100644 --- a/chrome/browser/renderer_host/backing_store_x.h +++ b/chrome/browser/renderer_host/backing_store_x.h @@ -11,6 +11,11 @@ #include "build/build_config.h" #include "chrome/browser/renderer_host/backing_store.h" +namespace gfx { +class Point; +class Rect; +} // namespace gfx + typedef struct _GdkDrawable GdkDrawable; class SkBitmap; @@ -34,10 +39,11 @@ class BackingStoreX : public BackingStore { XID root_window() const { return root_window_; } // Copy from the server-side backing store to the target window - // display: the display of the backing store and target window + // origin: the destination rectangle origin // damage: the area to copy // target: the X id of the target window - void XShowRect(const gfx::Rect& damage, XID target); + void XShowRect(const gfx::Point &origin, const gfx::Rect& damage, + XID target); // As above, but use Cairo instead of Xlib. void CairoShowRect(const gfx::Rect& damage, GdkDrawable* drawable); diff --git a/chrome/browser/renderer_host/render_widget_host_view_gtk.cc b/chrome/browser/renderer_host/render_widget_host_view_gtk.cc index b14fdcb..67b1a00 100644 --- a/chrome/browser/renderer_host/render_widget_host_view_gtk.cc +++ b/chrome/browser/renderer_host/render_widget_host_view_gtk.cc @@ -840,7 +840,7 @@ void RenderWidgetHostViewGtk::Paint(const gfx::Rect& damage_rect) { if (!visually_deemphasized_) { // In the common case, use XCopyArea. We don't draw more than once, so // we don't need to double buffer. - backing_store->XShowRect( + backing_store->XShowRect(gfx::Point(0, 0), paint_rect, x11_util::GetX11WindowFromGtkWidget(view_.get())); } else { // If the grey blend is showing, we make two drawing calls. Use double diff --git a/chrome/browser/renderer_host/render_widget_host_view_views.cc b/chrome/browser/renderer_host/render_widget_host_view_views.cc index a9bc958..1060779 100644 --- a/chrome/browser/renderer_host/render_widget_host_view_views.cc +++ b/chrome/browser/renderer_host/render_widget_host_view_views.cc @@ -22,6 +22,7 @@ #include "chrome/common/chrome_switches.h" #include "chrome/common/native_web_keyboard_event.h" #include "chrome/common/render_messages.h" +#include "gfx/canvas.h" #include "third_party/WebKit/WebKit/chromium/public/gtk/WebInputEventFactory.h" #include "third_party/WebKit/WebKit/chromium/public/WebInputEvent.h" #include "views/event.h" @@ -183,7 +184,7 @@ void RenderWidgetHostViewViews::SetSize(const gfx::Size& size) { if (requested_size_.width() != width || requested_size_.height() != height) { requested_size_ = gfx::Size(width, height); - SetBounds(x(), y(), requested_size_.width(), requested_size_.height()); + SetBounds(gfx::Rect(x(), y(), width, height)); host_->WasResized(); } } @@ -325,7 +326,9 @@ BackingStore* RenderWidgetHostViewViews::AllocBackingStore( } gfx::NativeView RenderWidgetHostViewViews::native_view() const { - return GetWidget()->GetNativeView(); + if (GetWidget()) + return GetWidget()->GetNativeView(); + return NULL; } void RenderWidgetHostViewViews::SetBackground(const SkBitmap& background) { @@ -334,6 +337,16 @@ void RenderWidgetHostViewViews::SetBackground(const SkBitmap& background) { } void RenderWidgetHostViewViews::Paint(gfx::Canvas* canvas) { + if (is_hidden_) { + return; + } + + // Paint a "hole" in the canvas so that the render of the web page is on + // top of whatever else has already been painted in the views hierarchy. + // Later views might still get to paint on top. + canvas->FillRectInt(SK_ColorBLACK, 0, 0, kMaxWindowWidth, kMaxWindowHeight, + SkXfermode::kClear_Mode); + // Don't do any painting if the GPU process is rendering directly // into the View. RenderWidgetHost* render_widget_host = GetRenderWidgetHost(); @@ -347,6 +360,9 @@ void RenderWidgetHostViewViews::Paint(gfx::Canvas* canvas) { // TODO(anicolao): get the damage somehow // invalid_rect_ = damage_rect; invalid_rect_ = bounds(); + gfx::Point origin; + ConvertPointToWidget(this, &origin); + about_to_validate_and_paint_ = true; BackingStoreX* backing_store = static_cast<BackingStoreX*>( host_->GetBackingStore(true)); @@ -364,7 +380,7 @@ void RenderWidgetHostViewViews::Paint(gfx::Canvas* canvas) { if (!visually_deemphasized_) { // In the common case, use XCopyArea. We don't draw more than once, so // we don't need to double buffer. - backing_store->XShowRect( + backing_store->XShowRect(origin, paint_rect, x11_util::GetX11WindowFromGtkWidget(native_view())); } else { // If the grey blend is showing, we make two drawing calls. Use double @@ -551,7 +567,7 @@ void RenderWidgetHostViewViews::DidGainFocus() { void RenderWidgetHostViewViews::WillLoseFocus() { // If we are showing a context menu, maintain the illusion that webkit has // focus. - if (!is_showing_context_menu_) + if (!is_showing_context_menu_ && !is_hidden_) GetRenderWidgetHost()->Blur(); } @@ -559,7 +575,7 @@ void RenderWidgetHostViewViews::WillLoseFocus() { void RenderWidgetHostViewViews::ShowCurrentCursor() { // The widget may not have a window. If that's the case, abort mission. This // is the same issue as that explained above in Paint(). - if (!native_view()->window) + if (!native_view() || !native_view()->window) return; native_cursor_ = current_cursor_.GetNativeCursor(); diff --git a/chrome/browser/ui/views/tab_contents/tab_contents_container.cc b/chrome/browser/ui/views/tab_contents/tab_contents_container.cc index eed5ea2..9ab6078 100644 --- a/chrome/browser/ui/views/tab_contents/tab_contents_container.cc +++ b/chrome/browser/ui/views/tab_contents/tab_contents_container.cc @@ -12,6 +12,13 @@ #include "chrome/browser/views/tab_contents/native_tab_contents_container.h" #include "chrome/common/notification_service.h" +#if defined(TOUCH_UI) +#include "chrome/browser/ui/views/tab_contents/native_tab_contents_container_gtk.h" +#include "chrome/browser/ui/views/tab_contents/tab_contents_view_views.h" +#include "views/border.h" +#include "views/fill_layout.h" +#endif + //////////////////////////////////////////////////////////////////////////////// // TabContentsContainer, public: @@ -29,29 +36,46 @@ TabContentsContainer::~TabContentsContainer() { void TabContentsContainer::ChangeTabContents(TabContents* contents) { if (tab_contents_) { +#if !defined(TOUCH_UI) native_container_->DetachContents(tab_contents_); +#endif tab_contents_->WasHidden(); RemoveObservers(); } +#if !defined(TOUCH_UI) TabContents* old_contents = tab_contents_; +#endif tab_contents_ = contents; // When detaching the last tab of the browser ChangeTabContents is invoked // with NULL. Don't attempt to do anything in that case. if (tab_contents_) { +#if defined(TOUCH_UI) + views::View *v = static_cast<TabContentsViewViews*>(contents->view()); + // Guard against re-adding ourselves, which happens because the NULL + // value is ignored by the pre-existing if() above. + if (v->GetParent() != this) { + AddChildView(v); + SetLayoutManager(new views::FillLayout()); + Layout(); + } +#else RenderWidgetHostViewChanged( old_contents ? old_contents->GetRenderWidgetHostView() : NULL, tab_contents_->GetRenderWidgetHostView()); native_container_->AttachContents(tab_contents_); +#endif AddObservers(); } } void TabContentsContainer::TabContentsFocused(TabContents* tab_contents) { - native_container_->TabContentsFocused(tab_contents); + if (native_container_) + native_container_->TabContentsFocused(tab_contents); } void TabContentsContainer::SetFastResize(bool fast_resize) { - native_container_->SetFastResize(fast_resize); + if (native_container_) + native_container_->SetFastResize(fast_resize); } //////////////////////////////////////////////////////////////////////////////// @@ -76,12 +100,16 @@ void TabContentsContainer::Observe(NotificationType type, // TabContentsContainer, View overrides: void TabContentsContainer::Layout() { +#if defined(TOUCH_UI) + views::View::Layout(); +#else if (native_container_) { if (reserved_area_delegate_) reserved_area_delegate_->UpdateReservedContentsRect(this); native_container_->GetView()->SetBounds(0, 0, width(), height()); native_container_->GetView()->Layout(); } +#endif } AccessibilityTypes::Role TabContentsContainer::GetAccessibleRole() { @@ -91,10 +119,14 @@ AccessibilityTypes::Role TabContentsContainer::GetAccessibleRole() { void TabContentsContainer::ViewHierarchyChanged(bool is_add, views::View* parent, views::View* child) { +#if defined(TOUCH_UI) + views::View::ViewHierarchyChanged(is_add, parent, child); +#else if (is_add && child == this) { native_container_ = NativeTabContentsContainer::CreateNativeContainer(this); AddChildView(native_container_->GetView()); } +#endif } //////////////////////////////////////////////////////////////////////////////// @@ -119,11 +151,15 @@ void TabContentsContainer::RemoveObservers() { void TabContentsContainer::RenderViewHostChanged(RenderViewHost* old_host, RenderViewHost* new_host) { +#if defined(TOUCH_UI) + NOTIMPLEMENTED(); // TODO(anicolao) +#else if (new_host) { RenderWidgetHostViewChanged( old_host ? old_host->view() : NULL, new_host->view()); } native_container_->RenderViewHostChanged(old_host, new_host); +#endif } void TabContentsContainer::TabContentsDestroyed(TabContents* contents) { diff --git a/chrome/browser/ui/views/tab_contents/tab_contents_view_views.cc b/chrome/browser/ui/views/tab_contents/tab_contents_view_views.cc new file mode 100644 index 0000000..10d3daf --- /dev/null +++ b/chrome/browser/ui/views/tab_contents/tab_contents_view_views.cc @@ -0,0 +1,299 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/ui/views/tab_contents/tab_contents_view_views.h" + +#include "base/string_util.h" +#include "build/build_config.h" +#include "chrome/browser/download/download_shelf.h" +#include "chrome/browser/renderer_host/render_view_host.h" +#include "chrome/browser/renderer_host/render_view_host_factory.h" +#include "chrome/browser/renderer_host/render_widget_host_view_views.h" +#include "chrome/browser/tab_contents/interstitial_page.h" +#include "chrome/browser/tab_contents/tab_contents.h" +#include "chrome/browser/tab_contents/tab_contents_delegate.h" +#include "chrome/browser/views/sad_tab_view.h" +#include "chrome/browser/views/tab_contents/render_view_context_menu_views.h" +#include "gfx/canvas_skia_paint.h" +#include "gfx/point.h" +#include "gfx/rect.h" +#include "gfx/size.h" +#include "views/controls/native/native_view_host.h" +#include "views/fill_layout.h" +#include "views/focus/focus_manager.h" +#include "views/focus/view_storage.h" +#include "views/screen.h" +#include "views/widget/widget.h" + +using WebKit::WebDragOperation; +using WebKit::WebDragOperationsMask; +using WebKit::WebInputEvent; + +// static +TabContentsView* TabContentsView::Create(TabContents* tab_contents) { + return new TabContentsViewViews(tab_contents); +} + +TabContentsViewViews::TabContentsViewViews(TabContents* tab_contents) + : TabContentsView(tab_contents), + sad_tab_(NULL), + ignore_next_char_event_(false) { + last_focused_view_storage_id_ = + views::ViewStorage::GetSharedInstance()->CreateStorageID(); + SetLayoutManager(new views::FillLayout()); +} + +TabContentsViewViews::~TabContentsViewViews() { + // Make sure to remove any stored view we may still have in the ViewStorage. + // + // It is possible the view went away before us, so we only do this if the + // view is registered. + views::ViewStorage* view_storage = views::ViewStorage::GetSharedInstance(); + if (view_storage->RetrieveView(last_focused_view_storage_id_) != NULL) + view_storage->RemoveView(last_focused_view_storage_id_); +} + +void TabContentsViewViews::AttachConstrainedWindow( + ConstrainedWindowGtk* constrained_window) { + // TODO(anicolao): reimplement all dialogs as DOMUI + NOTIMPLEMENTED(); +} + +void TabContentsViewViews::RemoveConstrainedWindow( + ConstrainedWindowGtk* constrained_window) { + // TODO(anicolao): reimplement all dialogs as DOMUI + NOTIMPLEMENTED(); +} + +void TabContentsViewViews::CreateView(const gfx::Size& initial_size) { + SetBounds(gfx::Rect(bounds().origin(), initial_size)); +} + +RenderWidgetHostView* TabContentsViewViews::CreateViewForWidget( + RenderWidgetHost* render_widget_host) { + if (render_widget_host->view()) { + // During testing, the view will already be set up in most cases to the + // test view, so we don't want to clobber it with a real one. To verify that + // this actually is happening (and somebody isn't accidentally creating the + // view twice), we check for the RVH Factory, which will be set when we're + // making special ones (which go along with the special views). + DCHECK(RenderViewHostFactory::has_factory()); + return render_widget_host->view(); + } + + // If we were showing sad tab, remove it now. + if (sad_tab_ != NULL) { + RemoveChildView(sad_tab_); + AddChildView(new views::View()); + sad_tab_ = NULL; + } + + RenderWidgetHostViewViews* view = + new RenderWidgetHostViewViews(render_widget_host); + AddChildView(view); + view->Show(); + view->InitAsChild(); + + // TODO(anicolao): implement drag'n'drop hooks if needed + + return view; +} + +gfx::NativeView TabContentsViewViews::GetNativeView() const { + return GetWidget()->GetNativeView(); +} + +gfx::NativeView TabContentsViewViews::GetContentNativeView() const { + RenderWidgetHostView* rwhv = tab_contents()->GetRenderWidgetHostView(); + if (!rwhv) + return NULL; + return rwhv->GetNativeView(); +} + +gfx::NativeWindow TabContentsViewViews::GetTopLevelNativeWindow() const { + GtkWidget* window = gtk_widget_get_ancestor(GetNativeView(), GTK_TYPE_WINDOW); + return window ? GTK_WINDOW(window) : NULL; +} + +void TabContentsViewViews::GetContainerBounds(gfx::Rect* out) const { + *out = bounds(); +} + +void TabContentsViewViews::StartDragging(const WebDropData& drop_data, + WebDragOperationsMask ops, + const SkBitmap& image, + const gfx::Point& image_offset) { + // TODO(anicolao): implement dragging +} + +void TabContentsViewViews::SetPageTitle(const std::wstring& title) { + // TODO(anicolao): figure out if there's anything useful to do here +} + +void TabContentsViewViews::OnTabCrashed() { +} + +void TabContentsViewViews::SizeContents(const gfx::Size& size) { + WasSized(size); + + // We need to send this immediately. + RenderWidgetHostView* rwhv = tab_contents()->GetRenderWidgetHostView(); + if (rwhv) + rwhv->SetSize(size); +} + +void TabContentsViewViews::Focus() { + if (tab_contents()->interstitial_page()) { + tab_contents()->interstitial_page()->Focus(); + return; + } + + if (tab_contents()->is_crashed() && sad_tab_ != NULL) { + sad_tab_->RequestFocus(); + return; + } + + RenderWidgetHostView* rwhv = tab_contents()->GetRenderWidgetHostView(); + gtk_widget_grab_focus(rwhv ? rwhv->GetNativeView() : GetNativeView()); +} + +void TabContentsViewViews::SetInitialFocus() { + if (tab_contents()->FocusLocationBarByDefault()) + tab_contents()->SetFocusToLocationBar(false); + else + Focus(); +} + +void TabContentsViewViews::StoreFocus() { + views::ViewStorage* view_storage = views::ViewStorage::GetSharedInstance(); + + if (view_storage->RetrieveView(last_focused_view_storage_id_) != NULL) + view_storage->RemoveView(last_focused_view_storage_id_); + + views::FocusManager* focus_manager = + views::FocusManager::GetFocusManagerForNativeView(GetNativeView()); + if (focus_manager) { + // |focus_manager| can be NULL if the tab has been detached but still + // exists. + views::View* focused_view = focus_manager->GetFocusedView(); + if (focused_view) + view_storage->StoreView(last_focused_view_storage_id_, focused_view); + } +} + +void TabContentsViewViews::RestoreFocus() { + views::ViewStorage* view_storage = views::ViewStorage::GetSharedInstance(); + views::View* last_focused_view = + view_storage->RetrieveView(last_focused_view_storage_id_); + if (!last_focused_view) { + SetInitialFocus(); + } else { + views::FocusManager* focus_manager = + views::FocusManager::GetFocusManagerForNativeView(GetNativeView()); + + // If you hit this DCHECK, please report it to Jay (jcampan). + DCHECK(focus_manager != NULL) << "No focus manager when restoring focus."; + + if (last_focused_view->IsFocusableInRootView() && focus_manager && + focus_manager->ContainsView(last_focused_view)) { + last_focused_view->RequestFocus(); + } else { + // The focused view may not belong to the same window hierarchy (e.g. + // if the location bar was focused and the tab is dragged out), or it may + // no longer be focusable (e.g. if the location bar was focused and then + // we switched to fullscreen mode). In that case we default to the + // default focus. + SetInitialFocus(); + } + view_storage->RemoveView(last_focused_view_storage_id_); + } +} + +void TabContentsViewViews::Paint(gfx::Canvas* canvas) { +} + +void TabContentsViewViews::UpdateDragCursor(WebDragOperation operation) { + NOTIMPLEMENTED(); + // It's not even clear a drag cursor will make sense for touch. + // TODO(anicolao): implement dragging +} + +void TabContentsViewViews::GotFocus() { + if (tab_contents()->delegate()) + tab_contents()->delegate()->TabContentsFocused(tab_contents()); +} + +void TabContentsViewViews::TakeFocus(bool reverse) { + if (tab_contents()->delegate() && + !tab_contents()->delegate()->TakeFocus(reverse)) { + + views::FocusManager* focus_manager = + views::FocusManager::GetFocusManagerForNativeView(GetNativeView()); + + // We may not have a focus manager if the tab has been switched before this + // message arrived. + if (focus_manager) + focus_manager->AdvanceFocus(reverse); + } +} + +void TabContentsViewViews::VisibilityChanged(views::View *, bool is_visible) { + if (is_visible) { + WasShown(); + } else { + WasHidden(); + } +} + +void TabContentsViewViews::ShowContextMenu(const ContextMenuParams& params) { + // Allow delegates to handle the context menu operation first. + if (tab_contents()->delegate()->HandleContextMenu(params)) + return; + + // TODO(anicolao): implement context menus for touch + NOTIMPLEMENTED(); +} + +void TabContentsViewViews::ShowPopupMenu(const gfx::Rect& bounds, + int item_height, + double item_font_size, + int selected_item, + const std::vector<WebMenuItem>& items, + bool right_aligned) { + // External popup menus are only used on Mac. + NOTREACHED(); +} + +void TabContentsViewViews::WasHidden() { + tab_contents()->HideContents(); +} + +void TabContentsViewViews::WasShown() { + tab_contents()->ShowContents(); +} + +void TabContentsViewViews::WasSized(const gfx::Size& size) { + // We have to check that the RenderWidgetHostView is the proper size. + // It can be wrong in cases where the renderer has died and the host + // view needed to be recreated. + bool needs_resize = size != size_; + + if (needs_resize) { + size_ = size; + if (tab_contents()->interstitial_page()) + tab_contents()->interstitial_page()->SetSize(size); + } + + RenderWidgetHostView* rwhv = tab_contents()->GetRenderWidgetHostView(); + if (rwhv && rwhv->GetViewBounds().size() != size) + rwhv->SetSize(size); + + if (needs_resize) + SetFloatingPosition(size); +} + +void TabContentsViewViews::SetFloatingPosition(const gfx::Size& size) { + // TODO(anicolao): rework this once we have DOMUI views for dialogs + SetBounds(x(), y(), size.width(), size.height()); +} diff --git a/chrome/browser/ui/views/tab_contents/tab_contents_view_views.h b/chrome/browser/ui/views/tab_contents/tab_contents_view_views.h new file mode 100644 index 0000000..dfb7ed7 --- /dev/null +++ b/chrome/browser/ui/views/tab_contents/tab_contents_view_views.h @@ -0,0 +1,128 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_VIEWS_TAB_CONTENTS_TAB_CONTENTS_VIEW_VIEWS_H_ +#define CHROME_BROWSER_VIEWS_TAB_CONTENTS_TAB_CONTENTS_VIEW_VIEWS_H_ +#pragma once + +#include <vector> + +#include "base/scoped_ptr.h" +#include "chrome/browser/tab_contents/tab_contents_view.h" +#include "gfx/size.h" +#include "views/view.h" + +class ConstrainedWindowGtk; +typedef struct _GtkFloatingContainer GtkFloatingContainer; +class RenderViewContextMenuViews; +class SadTabView; +class SkBitmap; +class TabContentsDragSource; +class WebDragDestGtk; + +namespace gfx { +class Point; +} // namespace gfx + +namespace views { +class NativeViewHost; +} // namespace views + +// Views-specific implementation of the TabContentsView for the touch UI. +class TabContentsViewViews : public TabContentsView, public views::View { + public: + // The corresponding TabContents is passed in the constructor, and manages our + // lifetime. This doesn't need to be the case, but is this way currently + // because that's what was easiest when they were split. + explicit TabContentsViewViews(TabContents* tab_contents); + virtual ~TabContentsViewViews(); + + // Unlike Windows, ConstrainedWindows need to collaborate with the + // TabContentsViewViews to position the dialogs. + void AttachConstrainedWindow(ConstrainedWindowGtk* constrained_window); + void RemoveConstrainedWindow(ConstrainedWindowGtk* constrained_window); + + // TabContentsView implementation + virtual void CreateView(const gfx::Size& initial_size); + virtual RenderWidgetHostView* CreateViewForWidget( + RenderWidgetHost* render_widget_host); + virtual gfx::NativeView GetNativeView() const; + virtual gfx::NativeView GetContentNativeView() const; + virtual gfx::NativeWindow GetTopLevelNativeWindow() const; + virtual void GetContainerBounds(gfx::Rect* out) const; + virtual void SetPageTitle(const std::wstring& title); + virtual void OnTabCrashed(); + virtual void SizeContents(const gfx::Size& size); + virtual void Focus(); + virtual void SetInitialFocus(); + virtual void StoreFocus(); + virtual void RestoreFocus(); + + // views::View implementation + virtual void Paint(gfx::Canvas* canvas); + + // Backend implementation of RenderViewHostDelegate::View. + virtual void ShowContextMenu(const ContextMenuParams& params); + virtual void ShowPopupMenu(const gfx::Rect& bounds, + int item_height, + double item_font_size, + int selected_item, + const std::vector<WebMenuItem>& items, + bool right_aligned); + virtual void StartDragging(const WebDropData& drop_data, + WebKit::WebDragOperationsMask ops_allowed, + const SkBitmap& image, + const gfx::Point& image_offset); + virtual void UpdateDragCursor(WebKit::WebDragOperation operation); + virtual void GotFocus(); + virtual void TakeFocus(bool reverse); + virtual void VisibilityChanged(views::View *, bool is_visible); + + private: + // Signal handlers ----------------------------------------------------------- + + // Handles notifying the TabContents and other operations when the window was + // shown or hidden. + void WasHidden(); + void WasShown(); + + // Handles resizing of the contents. This will notify the RenderWidgetHostView + // of the change, reposition popups, and the find in page bar. + void WasSized(const gfx::Size& size); + + // For any floating views (ConstrainedDialogs) this function centers them + // within this view. It's called whem a ConstrainedDialog is attached and + // when this view is resized. + void SetFloatingPosition(const gfx::Size& size); + + // Used to render the sad tab. This will be non-NULL only when the sad tab is + // visible. + SadTabView* sad_tab_; + + // Whether to ignore the next CHAR keyboard event. + bool ignore_next_char_event_; + + // The id used in the ViewStorage to store the last focused view. + int last_focused_view_storage_id_; + + // The context menu. Callbacks are asynchronous so we need to keep it around. + scoped_ptr<RenderViewContextMenuViews> context_menu_; + + // Handle drags from this TabContentsView. + // TODO(anicolao): figure out what's needed for drag'n'drop + + // The event for the last mouse down we handled. We need this for drags. + GdkEventButton last_mouse_down_; + + // Current size. See comment in WidgetGtk as to why this is cached. + gfx::Size size_; + + // Each individual UI for constrained dialogs currently displayed. The + // objects in this vector are owned by the TabContents, not the view. + std::vector<ConstrainedWindowGtk*> constrained_windows_; + + DISALLOW_COPY_AND_ASSIGN(TabContentsViewViews); +}; + +#endif // CHROME_BROWSER_VIEWS_TAB_CONTENTS_TAB_CONTENTS_VIEW_VIEWS_H_ diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index ebadabe..68d5ef5 100644 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi @@ -3317,6 +3317,8 @@ 'browser/ui/views/tab_contents/tab_contents_view_gtk.h', 'browser/ui/views/tab_contents/tab_contents_view_win.cc', 'browser/ui/views/tab_contents/tab_contents_view_win.h', + 'browser/ui/views/tab_contents/tab_contents_view_views.cc', + 'browser/ui/views/tab_contents/tab_contents_view_views.h', 'browser/ui/views/tabs/base_tab.cc', 'browser/ui/views/tabs/base_tab.h', 'browser/ui/views/tabs/base_tab_strip.cc', @@ -3448,12 +3450,12 @@ ], }, }], - ['use_gconf==0', { - 'sources!': [ + ['use_gconf==0', { + 'sources!': [ 'browser/gtk/gconf_titlebar_listener.cc', 'browser/gtk/gconf_titlebar_listener.h', - ], - }], + ], + }], ['use_gnome_keyring==0', { 'sources!': [ 'browser/password_manager/native_backend_gnome_x.h', @@ -3466,6 +3468,8 @@ 'browser/dom_ui/keyboard_ui.h', 'browser/renderer_host/render_widget_host_view_views.cc', 'browser/renderer_host/render_widget_host_view_views.h', + 'browser/ui/views/tab_contents/tab_contents_view_views.cc', + 'browser/ui/views/tab_contents/tab_contents_view_views.h', ], }], ['touchui==1', { @@ -3474,6 +3478,8 @@ ['exclude', '^browser/renderer_host/render_widget_host_view_gtk.h'], ['exclude', '^browser/renderer_host/gtk_im_context_wrapper.cc'], ['exclude', '^browser/renderer_host/gtk_im_context_wrapper.h'], + ['exclude', '^browser/views/tab_contents/tab_contents_view_gtk.cc'], + ['exclude', '^browser/views/tab_contents/tab_contents_view_gtk.h'], ], }], ['OS=="linux"', { @@ -4151,6 +4157,18 @@ ['exclude', '^browser/ui/views/autocomplete/autocomplete_popup_gtk.h'], ], }], + # Touch build only + ['OS=="linux" and toolkit_views==1 and touchui==1', { + 'sources/': [ + ['include', '^browser/ui/views/tab_contents/tab_contents_view_views.cc'], + ['include', '^browser/ui/views/tab_contents/tab_contents_view_views.h'], + ['exclude', '^browser/ui/views/tab_contents/tab_contents_view_gtk.cc'], + ['exclude', '^browser/ui/views/tab_contents/tab_contents_view_gtk.h'], + # TODO(anicolao): exclude these once we have DOMUI dialogs + # ['exclude', '^browser/gtk/constrained_window_gtk.cc'], + # ['exclude', '^browser/gtk/constrained_window_gtk.h'], + ], + }], ['OS=="linux" and chromeos==1',{ 'sources/': [ ['exclude', '^browser/extensions/extension_tts_api_linux.cc'], diff --git a/gfx/canvas.h b/gfx/canvas.h index 077a8a2..c68cdab 100644 --- a/gfx/canvas.h +++ b/gfx/canvas.h @@ -102,6 +102,11 @@ class Canvas { virtual void FillRectInt(const SkColor& color, int x, int y, int w, int h) = 0; + // Fills the specified region with the specified color and mode + virtual void FillRectInt(const SkColor& color, + int x, int y, int w, int h, + SkXfermode::Mode mode) = 0; + // Fills the specified region with the specified brush. virtual void FillRectInt(const gfx::Brush* brush, int x, int y, int w, int h) = 0; diff --git a/gfx/canvas_direct2d.cc b/gfx/canvas_direct2d.cc index 3dfcc851..585659d 100644 --- a/gfx/canvas_direct2d.cc +++ b/gfx/canvas_direct2d.cc @@ -209,6 +209,12 @@ void CanvasDirect2D::FillRectInt(const SkColor& color, rt_->FillRectangle(RectToRectF(x, y, w, h), solid_brush); } +void CanvasDirect2D::FillRectInt(const SkColor& color, + int x, int y, int w, int h, + SkXfermode::Mode mode) { + NOTIMPLEMENTED(); +} + void CanvasDirect2D::FillRectInt(const gfx::Brush* brush, int x, int y, int w, int h) { const Direct2DBrush* d2d_brush = static_cast<const Direct2DBrush*>(brush); diff --git a/gfx/canvas_direct2d.h b/gfx/canvas_direct2d.h index f7f0019..89ea448 100644 --- a/gfx/canvas_direct2d.h +++ b/gfx/canvas_direct2d.h @@ -33,6 +33,8 @@ class CanvasDirect2D : public Canvas { virtual void TranslateInt(int x, int y); virtual void ScaleInt(int x, int y); virtual void FillRectInt(const SkColor& color, int x, int y, int w, int h); + virtual void FillRectInt(const SkColor& color, int x, int y, int w, int h, + SkXfermode::Mode mode); virtual void FillRectInt(const gfx::Brush* brush, int x, int y, int w, int h); virtual void DrawRectInt(const SkColor& color, int x, int y, int w, int h); virtual void DrawRectInt(const SkColor& color, diff --git a/gfx/canvas_skia.cc b/gfx/canvas_skia.cc index dbf5d3a..017fd5f 100644 --- a/gfx/canvas_skia.cc +++ b/gfx/canvas_skia.cc @@ -105,10 +105,16 @@ void CanvasSkia::ScaleInt(int x, int y) { } void CanvasSkia::FillRectInt(const SkColor& color, int x, int y, int w, int h) { + FillRectInt(color, x, y, w, h, SkXfermode::kSrcOver_Mode); +} + +void CanvasSkia::FillRectInt(const SkColor& color, + int x, int y, int w, int h, + SkXfermode::Mode mode) { SkPaint paint; paint.setColor(color); paint.setStyle(SkPaint::kFill_Style); - paint.setXfermodeMode(SkXfermode::kSrcOver_Mode); + paint.setXfermodeMode(mode); DrawRectInt(x, y, w, h, paint); } diff --git a/gfx/canvas_skia.h b/gfx/canvas_skia.h index 153e812..7db41a0 100644 --- a/gfx/canvas_skia.h +++ b/gfx/canvas_skia.h @@ -95,6 +95,8 @@ class CanvasSkia : public skia::PlatformCanvas, virtual void TranslateInt(int x, int y); virtual void ScaleInt(int x, int y); virtual void FillRectInt(const SkColor& color, int x, int y, int w, int h); + virtual void FillRectInt(const SkColor& color, int x, int y, int w, int h, + SkXfermode::Mode mode); virtual void FillRectInt(const gfx::Brush* brush, int x, int y, int w, int h); virtual void DrawRectInt(const SkColor& color, int x, int y, int w, int h); virtual void DrawRectInt(const SkColor& color, |