diff options
author | estade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-05-15 21:52:48 +0000 |
---|---|---|
committer | estade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-05-15 21:52:48 +0000 |
commit | 0a2aeb81a06170cf4d99392b683736c46212f9ef (patch) | |
tree | 1c491dcbe56474ad5bbbd6da0cd47c75eca414d3 /chrome | |
parent | 26ee7556422eb077a813c9a15a03867779bb8188 (diff) | |
download | chromium_src-0a2aeb81a06170cf4d99392b683736c46212f9ef.zip chromium_src-0a2aeb81a06170cf4d99392b683736c46212f9ef.tar.gz chromium_src-0a2aeb81a06170cf4d99392b683736c46212f9ef.tar.bz2 |
Linux: Take download shelf and infobar close animations into account during render view sizing.
http://crbug.com/11080
Review URL: http://codereview.chromium.org/113322
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@16193 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
29 files changed, 177 insertions, 36 deletions
diff --git a/chrome/browser/browser.cc b/chrome/browser/browser.cc index e6b6598..13ca661 100644 --- a/chrome/browser/browser.cc +++ b/chrome/browser/browser.cc @@ -2002,6 +2002,10 @@ ExtensionFunctionDispatcher* Browser::CreateExtensionFunctionDispatcher( return new ExtensionFunctionDispatcher(render_view_host, this, extension_id); } +int Browser::GetExtraRenderViewHeight() const { + return window_->GetExtraRenderViewHeight(); +} + /////////////////////////////////////////////////////////////////////////////// // Browser, SelectFileDialog::Listener implementation: diff --git a/chrome/browser/browser.h b/chrome/browser/browser.h index a1b5e46..dac3877 100644 --- a/chrome/browser/browser.h +++ b/chrome/browser/browser.h @@ -499,6 +499,7 @@ class Browser : public TabStripModelDelegate, virtual ExtensionFunctionDispatcher *CreateExtensionFunctionDispatcher( RenderViewHost* render_view_host, const std::string& extension_id); + virtual int GetExtraRenderViewHeight() const; // Overridden from SelectFileDialog::Listener: virtual void FileSelected(const FilePath& path, int index, void* params); diff --git a/chrome/browser/browser_window.h b/chrome/browser/browser_window.h index c5e2027..d804bc1 100644 --- a/chrome/browser/browser_window.h +++ b/chrome/browser/browser_window.h @@ -180,6 +180,12 @@ class BrowserWindow { // indicating that it's time to redraw everything. virtual void UserChangedTheme() = 0; + // Get extra vertical height that the render view should add to its requests + // to webkit. This can help prevent sending extraneous layout/repaint requests + // when the delegate is in the process of resizing the tab contents view (e.g. + // during infobar animations). + virtual int GetExtraRenderViewHeight() const = 0; + // Construct a BrowserWindow implementation for the specified |browser|. static BrowserWindow* CreateBrowserWindow(Browser* browser); diff --git a/chrome/browser/cocoa/browser_window_cocoa.h b/chrome/browser/cocoa/browser_window_cocoa.h index ba9ea70..66b2ba0 100644 --- a/chrome/browser/cocoa/browser_window_cocoa.h +++ b/chrome/browser/cocoa/browser_window_cocoa.h @@ -68,6 +68,7 @@ class BrowserWindowCocoa : public BrowserWindow, virtual void ShowHTMLDialog(HtmlDialogUIDelegate* delegate, void* parent_window); virtual void UserChangedTheme(); + virtual int GetExtraRenderViewHeight() const; // Overridden from NotificationObserver virtual void Observe(NotificationType type, diff --git a/chrome/browser/cocoa/browser_window_cocoa.mm b/chrome/browser/cocoa/browser_window_cocoa.mm index 395817b..0da8a3f 100644 --- a/chrome/browser/cocoa/browser_window_cocoa.mm +++ b/chrome/browser/cocoa/browser_window_cocoa.mm @@ -232,6 +232,11 @@ void BrowserWindowCocoa::UserChangedTheme() { NOTIMPLEMENTED(); } +int BrowserWindowCocoa::GetExtraRenderViewHeight() const { + // Currently this is only used on linux. + return 0; +} + void BrowserWindowCocoa::Observe(NotificationType type, const NotificationSource& source, const NotificationDetails& details) { diff --git a/chrome/browser/download/download_shelf.h b/chrome/browser/download/download_shelf.h index 15410ae..1b455c0 100644 --- a/chrome/browser/download/download_shelf.h +++ b/chrome/browser/download/download_shelf.h @@ -43,6 +43,9 @@ class DownloadShelf { // the beginning Show and true at the beginning of a Hide. virtual bool IsShowing() const = 0; + // Returns whether the download shelf is showing the close animation. + virtual bool IsClosing() const = 0; + protected: TabContents* tab_contents_; diff --git a/chrome/browser/download/save_package.cc b/chrome/browser/download/save_package.cc index 85c3003..9356a68 100644 --- a/chrome/browser/download/save_package.cc +++ b/chrome/browser/download/save_package.cc @@ -252,7 +252,7 @@ bool SavePackage::Init() { FilePath(), Time::Now(), 0, -1, -1, false); download_->set_manager(tab_contents_->profile()->GetDownloadManager()); #if !defined(OS_MACOSX) - DownloadShelf* shelf = tab_contents_->GetDownloadShelf(); + DownloadShelf* shelf = tab_contents_->GetDownloadShelf(true); shelf->AddDownload(new SavePageModel(this, download_)); tab_contents_->SetDownloadShelfVisible(true); #else diff --git a/chrome/browser/gtk/browser_window_gtk.cc b/chrome/browser/gtk/browser_window_gtk.cc index bf441a5..49fc667 100644 --- a/chrome/browser/gtk/browser_window_gtk.cc +++ b/chrome/browser/gtk/browser_window_gtk.cc @@ -593,6 +593,13 @@ void BrowserWindowGtk::UserChangedTheme() { NOTIMPLEMENTED(); } +int BrowserWindowGtk::GetExtraRenderViewHeight() const { + // The download shelf is controlled by its TabContents, so we don't have to + // worry about it here. + // TODO(estade): take the bookmark bar into account as well. + return infobar_container_->TotalHeightOfClosingBars(); +} + void BrowserWindowGtk::ConfirmBrowserCloseWithPendingDownloads() { NOTIMPLEMENTED(); browser_->InProgressDownloadResponse(false); diff --git a/chrome/browser/gtk/browser_window_gtk.h b/chrome/browser/gtk/browser_window_gtk.h index f292cdf..c54a120 100644 --- a/chrome/browser/gtk/browser_window_gtk.h +++ b/chrome/browser/gtk/browser_window_gtk.h @@ -79,6 +79,7 @@ class BrowserWindowGtk : public BrowserWindow, virtual void ShowHTMLDialog(HtmlDialogUIDelegate* delegate, void* parent_window); virtual void UserChangedTheme(); + virtual int GetExtraRenderViewHeight() const; // Overridden from NotificationObserver: virtual void Observe(NotificationType type, diff --git a/chrome/browser/gtk/download_shelf_gtk.cc b/chrome/browser/gtk/download_shelf_gtk.cc index 3eb794c..f594a7f 100644 --- a/chrome/browser/gtk/download_shelf_gtk.cc +++ b/chrome/browser/gtk/download_shelf_gtk.cc @@ -138,6 +138,10 @@ bool DownloadShelfGtk::IsShowing() const { return slide_widget_->IsShowing(); } +bool DownloadShelfGtk::IsClosing() const { + return slide_widget_->IsClosing(); +} + void DownloadShelfGtk::RemoveDownloadItem(DownloadItemGtk* download_item) { DCHECK(download_item); std::vector<DownloadItemGtk*>::iterator i = diff --git a/chrome/browser/gtk/download_shelf_gtk.h b/chrome/browser/gtk/download_shelf_gtk.h index e2819a0..bc41647 100644 --- a/chrome/browser/gtk/download_shelf_gtk.h +++ b/chrome/browser/gtk/download_shelf_gtk.h @@ -28,6 +28,7 @@ class DownloadShelfGtk : public DownloadShelf { // DownloadShelf implementation. virtual void AddDownload(BaseDownloadItemModel* download_model); virtual bool IsShowing() const; + virtual bool IsClosing() const; private: // Remove |download_item| from the download shelf and delete it. diff --git a/chrome/browser/gtk/infobar_container_gtk.cc b/chrome/browser/gtk/infobar_container_gtk.cc index 3623497..a44ef65 100644 --- a/chrome/browser/gtk/infobar_container_gtk.cc +++ b/chrome/browser/gtk/infobar_container_gtk.cc @@ -15,28 +15,33 @@ namespace { -// Used by RemoveInfoBar to pass data to AnimateClosingForDelegate. -struct RemoveInfoBarData { - GtkWidget* container; - InfoBarDelegate* delegate; -}; - +// If |infobar_widget| matches |info_bar_delegate|, then close the infobar. void AnimateClosingForDelegate(GtkWidget* infobar_widget, - gpointer remove_info_bar_data) { + gpointer info_bar_delegate) { + InfoBarDelegate* delegate = + static_cast<InfoBarDelegate*>(info_bar_delegate); InfoBar* infobar = reinterpret_cast<InfoBar*>( g_object_get_data(G_OBJECT(infobar_widget), "info-bar")); - RemoveInfoBarData* data = - reinterpret_cast<RemoveInfoBarData*>(remove_info_bar_data); if (!infobar) { NOTREACHED(); return; } - if (data->delegate == infobar->delegate()) + if (delegate == infobar->delegate()) infobar->AnimateClose(); } +// Get the height of the widget and add it to |userdata|, but only if it is in +// the process of closing. +void SumClosingBarHeight(GtkWidget* widget, gpointer userdata) { + int* height_sum = static_cast<int*>(userdata); + InfoBar* infobar = reinterpret_cast<InfoBar*>( + g_object_get_data(G_OBJECT(widget), "info-bar")); + if (infobar->IsClosing()) + *height_sum += widget->allocation.height; +} + } // namespace // InfoBarContainerGtk, public: ------------------------------------------------ @@ -45,7 +50,7 @@ InfoBarContainerGtk::InfoBarContainerGtk(BrowserWindow* browser_window) : browser_window_(browser_window), tab_contents_(NULL), container_(gtk_vbox_new(FALSE, 0)) { - gtk_widget_show(container_.get()); + gtk_widget_show(widget()); } InfoBarContainerGtk::~InfoBarContainerGtk() { @@ -65,7 +70,7 @@ void InfoBarContainerGtk::ChangeTabContents(TabContents* contents) { Source<TabContents>(tab_contents_)); } - gtk_util::RemoveAllChildren(container_.get()); + gtk_util::RemoveAllChildren(widget()); tab_contents_ = contents; if (tab_contents_) { @@ -83,6 +88,12 @@ void InfoBarContainerGtk::RemoveDelegate(InfoBarDelegate* delegate) { tab_contents_->RemoveInfoBar(delegate); } +int InfoBarContainerGtk::TotalHeightOfClosingBars() const { + int sum = 0; + gtk_container_foreach(GTK_CONTAINER(widget()), SumClosingBarHeight, &sum); + return sum; +} + // InfoBarContainerGtk, NotificationObserver implementation: ------------------- void InfoBarContainerGtk::Observe(NotificationType type, @@ -109,7 +120,7 @@ void InfoBarContainerGtk::UpdateInfoBars() { void InfoBarContainerGtk::AddInfoBar(InfoBarDelegate* delegate, bool animate) { InfoBar* infobar = delegate->CreateInfoBar(); infobar->set_container(this); - gtk_box_pack_end(GTK_BOX(container_.get()), infobar->widget(), + gtk_box_pack_end(GTK_BOX(widget()), infobar->widget(), FALSE, FALSE, 0); if (animate) infobar->AnimateOpen(); @@ -118,8 +129,6 @@ void InfoBarContainerGtk::AddInfoBar(InfoBarDelegate* delegate, bool animate) { } void InfoBarContainerGtk::RemoveInfoBar(InfoBarDelegate* delegate) { - RemoveInfoBarData remove_info_bar_data = { container_.get(), delegate }; - - gtk_container_foreach(GTK_CONTAINER(container_.get()), - AnimateClosingForDelegate, &remove_info_bar_data); + gtk_container_foreach(GTK_CONTAINER(widget()), + AnimateClosingForDelegate, delegate); } diff --git a/chrome/browser/gtk/infobar_container_gtk.h b/chrome/browser/gtk/infobar_container_gtk.h index 60bd8d0..58e0c52 100644 --- a/chrome/browser/gtk/infobar_container_gtk.h +++ b/chrome/browser/gtk/infobar_container_gtk.h @@ -21,7 +21,7 @@ class InfoBarContainerGtk : public NotificationObserver { virtual ~InfoBarContainerGtk(); // Get the native widget. - GtkWidget* widget() { return container_.get(); } + GtkWidget* widget() const { return container_.get(); } // Changes the TabContents for which this container is showing InfoBars. Can // be NULL, in which case we will simply detach ourselves from the old tab @@ -33,6 +33,10 @@ class InfoBarContainerGtk : public NotificationObserver { // the InfoBar's close button handler. void RemoveDelegate(InfoBarDelegate* delegate); + // Returns the total pixel height of all infobars in this container that + // are currently closing. + int TotalHeightOfClosingBars() const; + private: // Overridden from NotificationObserver: virtual void Observe(NotificationType type, diff --git a/chrome/browser/gtk/infobar_gtk.cc b/chrome/browser/gtk/infobar_gtk.cc index e129fa9..60fa01d 100644 --- a/chrome/browser/gtk/infobar_gtk.cc +++ b/chrome/browser/gtk/infobar_gtk.cc @@ -105,6 +105,10 @@ void InfoBar::Close() { delete this; } +bool InfoBar::IsClosing() { + return slide_widget_->IsClosing(); +} + void InfoBar::RemoveInfoBar() const { container_->RemoveDelegate(delegate_); } diff --git a/chrome/browser/gtk/infobar_gtk.h b/chrome/browser/gtk/infobar_gtk.h index c39fceb..e3d5b1b 100644 --- a/chrome/browser/gtk/infobar_gtk.h +++ b/chrome/browser/gtk/infobar_gtk.h @@ -43,6 +43,9 @@ class InfoBar : public SlideAnimatorGtk::Delegate { // is called. void Close(); + // Returns true if the infobar is showing the close animation. + bool IsClosing(); + // SlideAnimatorGtk::Delegate implementation. virtual void Closed(); diff --git a/chrome/browser/gtk/slide_animator_gtk.cc b/chrome/browser/gtk/slide_animator_gtk.cc index 3cf004c..1f76457 100644 --- a/chrome/browser/gtk/slide_animator_gtk.cc +++ b/chrome/browser/gtk/slide_animator_gtk.cc @@ -32,7 +32,8 @@ SlideAnimatorGtk::SlideAnimatorGtk(GtkWidget* child, : child_(child), direction_(direction), delegate_(delegate), - fixed_needs_resize_(false) { + fixed_needs_resize_(false), + is_closing_(false) { widget_.Own(gtk_fixed_new()); gtk_fixed_put(GTK_FIXED(widget_.get()), child, 0, 0); gtk_widget_set_size_request(widget_.get(), -1, 0); @@ -64,6 +65,7 @@ SlideAnimatorGtk::~SlideAnimatorGtk() { } void SlideAnimatorGtk::Open() { + is_closing_ = false; gtk_widget_show_all(widget_.get()); animation_->Show(); } @@ -84,6 +86,7 @@ void SlideAnimatorGtk::OpenWithoutAnimation() { } void SlideAnimatorGtk::Close() { + is_closing_ = true; animation_->Hide(); } @@ -98,6 +101,10 @@ bool SlideAnimatorGtk::IsShowing() { return animation_->IsShowing(); } +bool SlideAnimatorGtk::IsClosing() { + return animation_->IsAnimating() && is_closing_; +} + void SlideAnimatorGtk::AnimationProgressed(const Animation* animation) { int showing_height = child_->allocation.height * animation_->GetCurrentValue(); diff --git a/chrome/browser/gtk/slide_animator_gtk.h b/chrome/browser/gtk/slide_animator_gtk.h index 7d9fcb6..3acc4f5 100644 --- a/chrome/browser/gtk/slide_animator_gtk.h +++ b/chrome/browser/gtk/slide_animator_gtk.h @@ -67,6 +67,9 @@ class SlideAnimatorGtk : public AnimationDelegate { // Returns whether the widget is visible. bool IsShowing(); + // Returns whether the widget is currently showing the close animation. + bool IsClosing(); + // AnimationDelegate implementation. void AnimationProgressed(const Animation* animation); void AnimationEnded(const Animation* animation); @@ -100,6 +103,9 @@ class SlideAnimatorGtk : public AnimationDelegate { // child widget has been allocated, at which point we will move it, and then // set this variable to false to indicate it should not be moved again. bool child_needs_move_; + + // Is true IFF Close() was called more recently than Open(). + bool is_closing_; }; #endif // CHROME_BROWSER_GTK_SLIDE_ANIMATOR_GTK_H_ 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 f44511e..ee2f7b9 100644 --- a/chrome/browser/renderer_host/render_widget_host_view_gtk.cc +++ b/chrome/browser/renderer_host/render_widget_host_view_gtk.cc @@ -39,8 +39,8 @@ class RenderWidgetHostViewGtkWidget { GDK_KEY_RELEASE_MASK); GTK_WIDGET_SET_FLAGS(widget, GTK_CAN_FOCUS); - g_signal_connect(widget, "configure-event", - G_CALLBACK(ConfigureEvent), host_view); + g_signal_connect(widget, "size-allocate", + G_CALLBACK(SizeAllocate), host_view); g_signal_connect(widget, "expose-event", G_CALLBACK(ExposeEvent), host_view); g_signal_connect(widget, "key-press-event", @@ -74,8 +74,8 @@ class RenderWidgetHostViewGtkWidget { } private: - static gboolean ConfigureEvent(GtkWidget* widget, GdkEventConfigure* config, - RenderWidgetHostViewGtk* host_view) { + static gboolean SizeAllocate(GtkWidget* widget, GtkAllocation* allocation, + RenderWidgetHostViewGtk* host_view) { host_view->GetRenderWidgetHost()->WasResized(); return FALSE; } diff --git a/chrome/browser/tab_contents/tab_contents.cc b/chrome/browser/tab_contents/tab_contents.cc index 9042518..af83bfd 100644 --- a/chrome/browser/tab_contents/tab_contents.cc +++ b/chrome/browser/tab_contents/tab_contents.cc @@ -919,7 +919,7 @@ void TabContents::SetDownloadShelfVisible(bool visible) { if (shelf_visible_ != visible) { if (visible) { // Invoke GetDownloadShelf to force the shelf to be created. - GetDownloadShelf(); + GetDownloadShelf(true); } shelf_visible_ = visible; @@ -951,7 +951,7 @@ void TabContents::OnStartDownload(DownloadItem* download) { TabContents* tab_contents = delegate()->GetConstrainingContents(this); // GetDownloadShelf creates the download shelf if it was not yet created. - tab_contents->GetDownloadShelf()->AddDownload( + tab_contents->GetDownloadShelf(true)->AddDownload( new DownloadItemModel(download)); tab_contents->SetDownloadShelfVisible(true); @@ -966,14 +966,14 @@ void TabContents::OnStartDownload(DownloadItem* download) { #endif } -DownloadShelf* TabContents::GetDownloadShelf() { - if (!download_shelf_.get()) +DownloadShelf* TabContents::GetDownloadShelf(bool create) { + if (!download_shelf_.get() && create) download_shelf_.reset(DownloadShelf::Create(this)); return download_shelf_.get(); } void TabContents::MigrateShelfFrom(TabContents* tab_contents) { - download_shelf_.reset(tab_contents->GetDownloadShelf()); + download_shelf_.reset(tab_contents->GetDownloadShelf(true)); download_shelf_->ChangeTabContents(tab_contents, this); tab_contents->ReleaseDownloadShelf(); } diff --git a/chrome/browser/tab_contents/tab_contents.h b/chrome/browser/tab_contents/tab_contents.h index cf25aba..3b749e6 100644 --- a/chrome/browser/tab_contents/tab_contents.h +++ b/chrome/browser/tab_contents/tab_contents.h @@ -415,8 +415,9 @@ class TabContents : public PageNavigator, // Displays the download shelf and animation when a download occurs. void OnStartDownload(DownloadItem* download); - // Returns the DownloadShelf, creating it if necessary. - DownloadShelf* GetDownloadShelf(); + // Returns the DownloadShelf. If the shelf doesn't exist and |create| is true, + // this function will create the shelf. + DownloadShelf* GetDownloadShelf(bool create); // Transfer the shelf view from |tab_contents| to the receiving TabContents. // |tab_contents| no longer owns the shelf after this call. The shelf is owned diff --git a/chrome/browser/tab_contents/tab_contents_delegate.h b/chrome/browser/tab_contents/tab_contents_delegate.h index 3485fb8..4ba9553 100644 --- a/chrome/browser/tab_contents/tab_contents_delegate.h +++ b/chrome/browser/tab_contents/tab_contents_delegate.h @@ -167,6 +167,13 @@ class TabContentsDelegate { return false; } + // Return much extra vertical space should be allotted to the + // render view widget during various animations (e.g. infobar closing). + // This is used to make painting look smoother. + virtual int GetExtraRenderViewHeight() { + return 0; + } + protected: ~TabContentsDelegate() {} diff --git a/chrome/browser/tab_contents/tab_contents_view_gtk.cc b/chrome/browser/tab_contents/tab_contents_view_gtk.cc index b9671be..59065ed 100644 --- a/chrome/browser/tab_contents/tab_contents_view_gtk.cc +++ b/chrome/browser/tab_contents/tab_contents_view_gtk.cc @@ -10,6 +10,8 @@ #include "base/string_util.h" #include "base/gfx/point.h" #include "base/gfx/rect.h" +#include "base/gfx/size.h" +#include "chrome/browser/download/download_shelf.h" #include "chrome/browser/gtk/browser_window_gtk.h" #include "chrome/browser/gtk/sad_tab_gtk.h" #include "chrome/browser/renderer_host/render_view_host.h" @@ -58,6 +60,16 @@ gboolean OnMouseMove(GtkWidget* widget, GdkEventMotion* event, return FALSE; } +// Used with gtk_container_foreach to change the sizes of the children of +// |fixed_|. +void SetSizeRequest(GtkWidget* widget, gpointer userdata) { + gfx::Size* size = static_cast<gfx::Size*>(userdata); + if (widget->allocation.width != size->width() || + widget->allocation.height != size->height()) { + gtk_widget_set_size_request(widget, size->width(), size->height()); + } +} + } // namespace // static @@ -68,6 +80,11 @@ TabContentsView* TabContentsView::Create(TabContents* tab_contents) { TabContentsViewGtk::TabContentsViewGtk(TabContents* tab_contents) : TabContentsView(tab_contents), vbox_(gtk_vbox_new(FALSE, 0)) { + fixed_ = gtk_fixed_new(); + gtk_box_pack_start(GTK_BOX(vbox_.get()), fixed_, TRUE, TRUE, 0); + g_signal_connect(fixed_, "size-allocate", + G_CALLBACK(OnSizeAllocate), this); + gtk_widget_show(fixed_); registrar_.Add(this, NotificationType::TAB_CONTENTS_CONNECTED, Source<TabContents>(tab_contents)); registrar_.Add(this, NotificationType::TAB_CONTENTS_DISCONNECTED, @@ -108,7 +125,8 @@ RenderWidgetHostView* TabContentsViewGtk::CreateViewForWidget( GDK_POINTER_MOTION_MASK); g_signal_connect(content_view, "button-press-event", G_CALLBACK(OnMouseDown), this); - gtk_box_pack_start(GTK_BOX(vbox_.get()), content_view, TRUE, TRUE, 0); + + InsertIntoContentArea(content_view); return view; } @@ -250,8 +268,7 @@ void TabContentsViewGtk::Observe(NotificationType type, } case NotificationType::TAB_CONTENTS_DISCONNECTED: { sad_tab_.reset(new SadTabGtk); - gtk_box_pack_start( - GTK_BOX(vbox_.get()), sad_tab_->widget(), TRUE, TRUE, 0); + InsertIntoContentArea(sad_tab_->widget()); gtk_widget_show(sad_tab_->widget()); break; } @@ -278,8 +295,26 @@ void TabContentsViewGtk::StartDragging(const WebDropData& drop_data) { tab_contents()->render_view_host()->DragSourceSystemDragEnded(); } +void TabContentsViewGtk::InsertIntoContentArea(GtkWidget* widget) { + gtk_fixed_put(GTK_FIXED(fixed_), widget, 0, 0); +} + gboolean TabContentsViewGtk::OnMouseDown(GtkWidget* widget, GdkEventButton* event, TabContentsViewGtk* view) { view->last_mouse_down_time_ = event->time; return FALSE; } + +gboolean TabContentsViewGtk::OnSizeAllocate(GtkWidget* widget, + GtkAllocation* allocation, + TabContentsViewGtk* view) { + int width = allocation->width; + DownloadShelf* shelf = view->tab_contents()->GetDownloadShelf(false); + int height = shelf && shelf->IsClosing() ? + widget->parent->allocation.height : allocation->height; + height += view->tab_contents()->delegate()->GetExtraRenderViewHeight(); + gfx::Size size(width, height); + gtk_container_foreach(GTK_CONTAINER(widget), SetSizeRequest, &size); + + return FALSE; +} diff --git a/chrome/browser/tab_contents/tab_contents_view_gtk.h b/chrome/browser/tab_contents/tab_contents_view_gtk.h index 3120cc3..cebb637a 100644 --- a/chrome/browser/tab_contents/tab_contents_view_gtk.h +++ b/chrome/browser/tab_contents/tab_contents_view_gtk.h @@ -5,6 +5,8 @@ #ifndef CHROME_BROWSER_TAB_CONTENTS_TAB_CONTENTS_VIEW_GTK_H_ #define CHROME_BROWSER_TAB_CONTENTS_TAB_CONTENTS_VIEW_GTK_H_ +#include <gtk/gtk.h> + #include "base/scoped_ptr.h" #include "chrome/browser/gtk/focus_store_gtk.h" #include "chrome/browser/tab_contents/tab_contents_view.h" @@ -68,13 +70,28 @@ class TabContentsViewGtk : public TabContentsView, const NotificationDetails& details); private: + // Insert the given widget into the content area. Should only be used for + // web pages and the like (including interstitials and sad tab). Note that + // this will be perfectly happy to insert overlapping render views, so care + // should be taken that the correct one is hidden/shown. + void InsertIntoContentArea(GtkWidget* widget); + // We keep track of the timestamp of the latest mousedown event. static gboolean OnMouseDown(GtkWidget* widget, GdkEventButton* event, TabContentsViewGtk* view); + // Used to propagate size changes on |fixed_| to its children. + static gboolean OnSizeAllocate(GtkWidget* widget, + GtkAllocation* config, + TabContentsViewGtk* view); + // The native widget for the tab. OwnedWidgetGtk vbox_; + // This container holds the tab's web page views. It is a GtkFixed so that we + // can control the size of the web pages. + GtkWidget* fixed_; + // The context menu is reset every time we show it, but we keep a pointer to // between uses so that it won't go out of scope before we're done with it. scoped_ptr<RenderViewContextMenuGtk> context_menu_; diff --git a/chrome/browser/views/download_shelf_view.cc b/chrome/browser/views/download_shelf_view.cc index bd6a7b1..8e3353a 100644 --- a/chrome/browser/views/download_shelf_view.cc +++ b/chrome/browser/views/download_shelf_view.cc @@ -304,3 +304,8 @@ void DownloadShelfView::ButtonPressed(views::Button* button) { bool DownloadShelfView::IsShowing() const { return shelf_animation_->IsShowing(); } + +bool DownloadShelfView::IsClosing() const { + // TODO(estade): This is never called. For now just return false. + return false; +} diff --git a/chrome/browser/views/download_shelf_view.h b/chrome/browser/views/download_shelf_view.h index 1c1ee23..0b722b8 100644 --- a/chrome/browser/views/download_shelf_view.h +++ b/chrome/browser/views/download_shelf_view.h @@ -56,6 +56,7 @@ class DownloadShelfView : public DownloadShelf, // Implementation of DownloadShelf. virtual void AddDownload(BaseDownloadItemModel* download_model); virtual bool IsShowing() const; + virtual bool IsClosing() const; // Removes a specified download view. The supplied view is deleted after // it's removed. diff --git a/chrome/browser/views/frame/browser_view.cc b/chrome/browser/views/frame/browser_view.cc index 4adacf9..e12d4b1 100644 --- a/chrome/browser/views/frame/browser_view.cc +++ b/chrome/browser/views/frame/browser_view.cc @@ -737,7 +737,7 @@ gfx::Rect BrowserView::GetRootWindowResizerRect() const { // Other tests should be added here if we add more bottom shelves. TabContents* current_tab = browser_->GetSelectedTabContents(); if (current_tab && current_tab->IsDownloadShelfVisible()) { - DownloadShelf* download_shelf = current_tab->GetDownloadShelf(); + DownloadShelf* download_shelf = current_tab->GetDownloadShelf(true); if (download_shelf && download_shelf->IsShowing()) return gfx::Rect(); } @@ -863,6 +863,11 @@ void BrowserView::UserChangedTheme() { frame_->GetRootView()->SchedulePaint(); } +int BrowserView::GetExtraRenderViewHeight() const { + // Currently this is only used on linux. + return 0; +} + /////////////////////////////////////////////////////////////////////////////// // BrowserView, BrowserWindowTesting implementation: @@ -1453,7 +1458,8 @@ bool BrowserView::MaybeShowInfoBar(TabContents* contents) { bool BrowserView::MaybeShowDownloadShelf(TabContents* contents) { views::View* new_shelf = NULL; if (contents && contents->IsDownloadShelfVisible()) { - new_shelf = static_cast<DownloadShelfView*>(contents->GetDownloadShelf()); + new_shelf = + static_cast<DownloadShelfView*>(contents->GetDownloadShelf(true)); if (new_shelf != active_download_shelf_) new_shelf->AddChildView(new ResizeCorner()); } diff --git a/chrome/browser/views/frame/browser_view.h b/chrome/browser/views/frame/browser_view.h index 6a2d6af..74b04c2 100644 --- a/chrome/browser/views/frame/browser_view.h +++ b/chrome/browser/views/frame/browser_view.h @@ -205,6 +205,7 @@ class BrowserView : public BrowserWindow, virtual void ShowHTMLDialog(HtmlDialogUIDelegate* delegate, void* parent_window); virtual void UserChangedTheme(); + virtual int GetExtraRenderViewHeight() const; // Overridden from BrowserWindowTesting: virtual BookmarkBarView* GetBookmarkBarView() const; diff --git a/chrome/common/temp_scaffolding_stubs.cc b/chrome/common/temp_scaffolding_stubs.cc index 911eb46..938398a 100644 --- a/chrome/common/temp_scaffolding_stubs.cc +++ b/chrome/common/temp_scaffolding_stubs.cc @@ -215,6 +215,7 @@ class DownloadShelfMac : public DownloadShelf { : DownloadShelf(tab_contents) { } virtual void AddDownload(BaseDownloadItemModel* download_model) { } virtual bool IsShowing() const { return false; } + virtual bool IsClosing() const { return false; } }; // static diff --git a/chrome/test/test_browser_window.h b/chrome/test/test_browser_window.h index 6d7e92e..42703e7 100644 --- a/chrome/test/test_browser_window.h +++ b/chrome/test/test_browser_window.h @@ -63,6 +63,7 @@ class TestBrowserWindow : public BrowserWindow { virtual void ShowHTMLDialog(HtmlDialogUIDelegate* delegate, void* parent_window) {} virtual void UserChangedTheme() {} + virtual int GetExtraRenderViewHeight() const { return 0; } protected: virtual void DestroyBrowser() {} |