diff options
author | jianli@chromium.org <jianli@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-05-17 11:29:25 +0000 |
---|---|---|
committer | jianli@chromium.org <jianli@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-05-17 11:29:25 +0000 |
commit | f079715313c3335f6d28d4d2f94382bf840f807f (patch) | |
tree | 663dc579183543b44461d74eed2fa473c9fb8a6e /chrome/browser | |
parent | 13c68b62a59a0483b59dff3eb75f2ac77c6166b2 (diff) | |
download | chromium_src-f079715313c3335f6d28d4d2f94382bf840f807f.zip chromium_src-f079715313c3335f6d28d4d2f94382bf840f807f.tar.gz chromium_src-f079715313c3335f6d28d4d2f94382bf840f807f.tar.bz2 |
Fix the problem that black background window might occasionally appear in front on Windows
When a new panel is added to a stack, the following things occur:
1) The panel is initially created as always on top on Windows.
2) The panel is changed to non-always-on-top.
3) The background stack window is made to the owner of the new panel window.
4) The background stack window is set to behind the new panel window in z-order.
Occasionally, step 2 might be run after step 4. When this occurs, after step 1, 3 and 4, the background stack window will automatically obtain the always-on-top state since the panel window behind which is set to is always-on-top. For most of time, running step 2 after 4 will remove the always-on-top state for both new panel window and background stack window. However, if chrome is not foreground application, Windows system might fail to deprive the always-on-top state for the background stack window.
The fix is to create the panel window with always-on-top state depending on its collection.
BUG=241224
TEST=Manual test by following the bug report
Review URL: https://chromiumcodereview.appspot.com/14956006
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@200788 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser')
-rw-r--r-- | chrome/browser/ui/cocoa/panels/panel_cocoa.h | 2 | ||||
-rw-r--r-- | chrome/browser/ui/cocoa/panels/panel_cocoa.mm | 12 | ||||
-rw-r--r-- | chrome/browser/ui/gtk/panels/panel_gtk.cc | 10 | ||||
-rw-r--r-- | chrome/browser/ui/gtk/panels/panel_gtk.h | 2 | ||||
-rw-r--r-- | chrome/browser/ui/panels/detached_panel_collection.cc | 5 | ||||
-rw-r--r-- | chrome/browser/ui/panels/detached_panel_collection.h | 1 | ||||
-rw-r--r-- | chrome/browser/ui/panels/docked_panel_collection.cc | 5 | ||||
-rw-r--r-- | chrome/browser/ui/panels/docked_panel_collection.h | 1 | ||||
-rw-r--r-- | chrome/browser/ui/panels/panel.cc | 6 | ||||
-rw-r--r-- | chrome/browser/ui/panels/panel.h | 5 | ||||
-rw-r--r-- | chrome/browser/ui/panels/panel_collection.h | 2 | ||||
-rw-r--r-- | chrome/browser/ui/panels/panel_manager.cc | 3 | ||||
-rw-r--r-- | chrome/browser/ui/panels/stacked_panel_collection.cc | 5 | ||||
-rw-r--r-- | chrome/browser/ui/panels/stacked_panel_collection.h | 1 | ||||
-rw-r--r-- | chrome/browser/ui/views/panels/panel_view.cc | 17 | ||||
-rw-r--r-- | chrome/browser/ui/views/panels/panel_view.h | 2 |
16 files changed, 51 insertions, 28 deletions
diff --git a/chrome/browser/ui/cocoa/panels/panel_cocoa.h b/chrome/browser/ui/cocoa/panels/panel_cocoa.h index 29648c8..e5f15b3 100644 --- a/chrome/browser/ui/cocoa/panels/panel_cocoa.h +++ b/chrome/browser/ui/cocoa/panels/panel_cocoa.h @@ -18,7 +18,7 @@ class Panel; // interact with this object when it needs to manipulate the window. class PanelCocoa : public NativePanel { public: - PanelCocoa(Panel* panel, const gfx::Rect& bounds); + PanelCocoa(Panel* panel, const gfx::Rect& bounds, bool always_on_top); virtual ~PanelCocoa(); // Overridden from NativePanel diff --git a/chrome/browser/ui/cocoa/panels/panel_cocoa.mm b/chrome/browser/ui/cocoa/panels/panel_cocoa.mm index 357f07e..01375ce 100644 --- a/chrome/browser/ui/cocoa/panels/panel_cocoa.mm +++ b/chrome/browser/ui/cocoa/panels/panel_cocoa.mm @@ -30,14 +30,18 @@ const int kMinimumWindowSize = 1; // Overall chain of ownership is: // PanelWindowControllerCocoa -> PanelCocoa -> Panel. // static -NativePanel* Panel::CreateNativePanel(Panel* panel, const gfx::Rect& bounds) { - return new PanelCocoa(panel, bounds); +NativePanel* Panel::CreateNativePanel(Panel* panel, + const gfx::Rect& bounds, + bool always_on_top) { + return new PanelCocoa(panel, bounds, always_on_top); } -PanelCocoa::PanelCocoa(Panel* panel, const gfx::Rect& bounds) +PanelCocoa::PanelCocoa(Panel* panel, + const gfx::Rect& bounds, + bool always_on_top) : panel_(panel), bounds_(bounds), - always_on_top_(false), + always_on_top_(always_on_top), is_shown_(false), attention_request_id_(0), corner_style_(panel::ALL_ROUNDED) { diff --git a/chrome/browser/ui/gtk/panels/panel_gtk.cc b/chrome/browser/ui/gtk/panels/panel_gtk.cc index d8a7160..8118748 100644 --- a/chrome/browser/ui/gtk/panels/panel_gtk.cc +++ b/chrome/browser/ui/gtk/panels/panel_gtk.cc @@ -198,16 +198,18 @@ void SetFrameSize(const gfx::Size& new_size) { } // static -NativePanel* Panel::CreateNativePanel(Panel* panel, const gfx::Rect& bounds) { - PanelGtk* panel_gtk = new PanelGtk(panel, bounds); +NativePanel* Panel::CreateNativePanel(Panel* panel, + const gfx::Rect& bounds, + bool always_on_top) { + PanelGtk* panel_gtk = new PanelGtk(panel, bounds, always_on_top); panel_gtk->Init(); return panel_gtk; } -PanelGtk::PanelGtk(Panel* panel, const gfx::Rect& bounds) +PanelGtk::PanelGtk(Panel* panel, const gfx::Rect& bounds, bool always_on_top) : panel_(panel), bounds_(bounds), - always_on_top_(false), + always_on_top_(always_on_top), is_shown_(false), paint_state_(PAINT_AS_INACTIVE), is_drawing_attention_(false), diff --git a/chrome/browser/ui/gtk/panels/panel_gtk.h b/chrome/browser/ui/gtk/panels/panel_gtk.h index d24af9d..8b76023 100644 --- a/chrome/browser/ui/gtk/panels/panel_gtk.h +++ b/chrome/browser/ui/gtk/panels/panel_gtk.h @@ -37,7 +37,7 @@ class PanelGtk : public NativePanel, PAINT_FOR_ATTENTION }; - PanelGtk(Panel* panel, const gfx::Rect& bounds); + PanelGtk(Panel* panel, const gfx::Rect& bounds, bool always_on_top); virtual ~PanelGtk(); void Init(); diff --git a/chrome/browser/ui/panels/detached_panel_collection.cc b/chrome/browser/ui/panels/detached_panel_collection.cc index 3437237..d525dac 100644 --- a/chrome/browser/ui/panels/detached_panel_collection.cc +++ b/chrome/browser/ui/panels/detached_panel_collection.cc @@ -190,6 +190,10 @@ bool DetachedPanelCollection::IsPanelMinimized(const Panel* panel) const { return false; } +bool DetachedPanelCollection::UsesAlwaysOnTopPanels() const { + return false; +} + void DetachedPanelCollection::SavePanelPlacement(Panel* panel) { DCHECK(!saved_panel_placement_.panel); saved_panel_placement_.panel = panel; @@ -234,7 +238,6 @@ void DetachedPanelCollection::UpdatePanelOnCollectionChange(Panel* panel) { panel->set_attention_mode( static_cast<Panel::AttentionMode>(Panel::USE_PANEL_ATTENTION | Panel::USE_SYSTEM_ATTENTION)); - panel->SetAlwaysOnTop(false); panel->ShowShadow(true); panel->EnableResizeByMouse(true); panel->UpdateMinimizeRestoreButtonVisibility(); diff --git a/chrome/browser/ui/panels/detached_panel_collection.h b/chrome/browser/ui/panels/detached_panel_collection.h index 2720bfe..21aeeac 100644 --- a/chrome/browser/ui/panels/detached_panel_collection.h +++ b/chrome/browser/ui/panels/detached_panel_collection.h @@ -50,6 +50,7 @@ class DetachedPanelCollection : public PanelCollection { virtual bool CanShowMinimizeButton(const Panel* panel) const OVERRIDE; virtual bool CanShowRestoreButton(const Panel* panel) const OVERRIDE; virtual bool IsPanelMinimized(const Panel* panel) const OVERRIDE; + virtual bool UsesAlwaysOnTopPanels() const OVERRIDE; virtual void SavePanelPlacement(Panel* panel) OVERRIDE; virtual void RestorePanelToSavedPlacement() OVERRIDE; virtual void DiscardSavedPanelPlacement() OVERRIDE; diff --git a/chrome/browser/ui/panels/docked_panel_collection.cc b/chrome/browser/ui/panels/docked_panel_collection.cc index f17549f..e688b0c 100644 --- a/chrome/browser/ui/panels/docked_panel_collection.cc +++ b/chrome/browser/ui/panels/docked_panel_collection.cc @@ -421,6 +421,10 @@ bool DockedPanelCollection::IsPanelMinimized(const Panel* panel) const { return panel->expansion_state() != Panel::EXPANDED; } +bool DockedPanelCollection::UsesAlwaysOnTopPanels() const { + return true; +} + void DockedPanelCollection::UpdateMinimizedPanelCount() { int prev_minimized_panel_count = minimized_panel_count_; minimized_panel_count_ = 0; @@ -760,7 +764,6 @@ void DockedPanelCollection::CloseAll() { void DockedPanelCollection::UpdatePanelOnCollectionChange(Panel* panel) { panel->set_attention_mode(Panel::USE_PANEL_ATTENTION); - panel->SetAlwaysOnTop(true); panel->ShowShadow(true); panel->EnableResizeByMouse(true); panel->UpdateMinimizeRestoreButtonVisibility(); diff --git a/chrome/browser/ui/panels/docked_panel_collection.h b/chrome/browser/ui/panels/docked_panel_collection.h index ccf12ea8..799176d 100644 --- a/chrome/browser/ui/panels/docked_panel_collection.h +++ b/chrome/browser/ui/panels/docked_panel_collection.h @@ -64,6 +64,7 @@ class DockedPanelCollection : virtual bool CanShowMinimizeButton(const Panel* panel) const OVERRIDE; virtual bool CanShowRestoreButton(const Panel* panel) const OVERRIDE; virtual bool IsPanelMinimized(const Panel* panel) const OVERRIDE; + virtual bool UsesAlwaysOnTopPanels() const OVERRIDE; virtual void SavePanelPlacement(Panel* panel) OVERRIDE; virtual void RestorePanelToSavedPlacement() OVERRIDE; virtual void DiscardSavedPanelPlacement() OVERRIDE; diff --git a/chrome/browser/ui/panels/panel.cc b/chrome/browser/ui/panels/panel.cc index 02af37e..d003bbb 100644 --- a/chrome/browser/ui/panels/panel.cc +++ b/chrome/browser/ui/panels/panel.cc @@ -498,14 +498,16 @@ panel::Resizability Panel::CanResizeByMouse() const { return collection_->GetPanelResizability(this); } -void Panel::Initialize(const GURL& url, const gfx::Rect& bounds) { +void Panel::Initialize(const GURL& url, + const gfx::Rect& bounds, + bool always_on_top) { DCHECK(!initialized_); DCHECK(!collection_); // Cannot be added to a collection until fully created. DCHECK_EQ(EXPANDED, expansion_state_); DCHECK(!bounds.IsEmpty()); initialized_ = true; full_size_ = bounds.size(); - native_panel_ = CreateNativePanel(this, bounds); + native_panel_ = CreateNativePanel(this, bounds, always_on_top); extension_window_controller_.reset( new panel_internal::PanelExtensionWindowController(this, profile_)); diff --git a/chrome/browser/ui/panels/panel.h b/chrome/browser/ui/panels/panel.h index 1542aa9..deda724 100644 --- a/chrome/browser/ui/panels/panel.h +++ b/chrome/browser/ui/panels/panel.h @@ -146,7 +146,8 @@ class Panel : public BaseWindow, // Construct a native panel implementation. static NativePanel* CreateNativePanel(Panel* panel, - const gfx::Rect& bounds); + const gfx::Rect& bounds, + bool always_on_top); NativePanel* native_panel() const { return native_panel_; } @@ -199,7 +200,7 @@ class Panel : public BaseWindow, // Panel must be initialized to be "fully created" and ready for use. // Only called by PanelManager. bool initialized() const { return initialized_; } - void Initialize(const GURL& url, const gfx::Rect& bounds); + void Initialize(const GURL& url, const gfx::Rect& bounds, bool always_on_top); // This is different from BaseWindow::SetBounds(): // * SetPanelBounds() is only called by PanelManager to manage its position. diff --git a/chrome/browser/ui/panels/panel_collection.h b/chrome/browser/ui/panels/panel_collection.h index 6bc4064..dc53348 100644 --- a/chrome/browser/ui/panels/panel_collection.h +++ b/chrome/browser/ui/panels/panel_collection.h @@ -128,6 +128,8 @@ class PanelCollection { virtual bool IsPanelMinimized(const Panel* panel) const = 0; + virtual bool UsesAlwaysOnTopPanels() const = 0; + // Saves/restores/discards the placement information of |panel|. This is // useful in bringing back the dragging panel to its original positioning // when the drag is cancelled. After the placement information is saved, diff --git a/chrome/browser/ui/panels/panel_manager.cc b/chrome/browser/ui/panels/panel_manager.cc index ab68a56..ef1b1f9 100644 --- a/chrome/browser/ui/panels/panel_manager.cc +++ b/chrome/browser/ui/panels/panel_manager.cc @@ -270,7 +270,7 @@ Panel* PanelManager::CreatePanel(const std::string& app_name, adjusted_requested_bounds); bounds.AdjustToFit(work_area); - panel->Initialize(url, bounds); + panel->Initialize(url, bounds, collection->UsesAlwaysOnTopPanels()); // Auto resizable feature is enabled only if no initial size is requested. if (auto_sizing_enabled() && requested_bounds.width() == 0 && @@ -488,6 +488,7 @@ void PanelManager::MovePanelToCollection( target_collection->AddPanel(panel, positioning_mask); target_collection->UpdatePanelOnCollectionChange(panel); + panel->SetAlwaysOnTop(target_collection->UsesAlwaysOnTopPanels()); } bool PanelManager::ShouldBringUpTitlebars(int mouse_x, int mouse_y) const { diff --git a/chrome/browser/ui/panels/stacked_panel_collection.cc b/chrome/browser/ui/panels/stacked_panel_collection.cc index 7e1cc83..6286e37 100644 --- a/chrome/browser/ui/panels/stacked_panel_collection.cc +++ b/chrome/browser/ui/panels/stacked_panel_collection.cc @@ -472,6 +472,10 @@ bool StackedPanelCollection::IsPanelMinimized(const Panel* panel) const { return panel->expansion_state() != Panel::EXPANDED; } +bool StackedPanelCollection::UsesAlwaysOnTopPanels() const { + return false; +} + void StackedPanelCollection::SavePanelPlacement(Panel* panel) { DCHECK(!saved_panel_placement_.panel); saved_panel_placement_.panel = panel; @@ -614,7 +618,6 @@ void StackedPanelCollection::UpdatePanelOnCollectionChange(Panel* panel) { panel->set_attention_mode( static_cast<Panel::AttentionMode>(Panel::USE_PANEL_ATTENTION | Panel::USE_SYSTEM_ATTENTION)); - panel->SetAlwaysOnTop(false); panel->ShowShadow(false); panel->EnableResizeByMouse(true); panel->UpdateMinimizeRestoreButtonVisibility(); diff --git a/chrome/browser/ui/panels/stacked_panel_collection.h b/chrome/browser/ui/panels/stacked_panel_collection.h index 2c95cab..a8219cd 100644 --- a/chrome/browser/ui/panels/stacked_panel_collection.h +++ b/chrome/browser/ui/panels/stacked_panel_collection.h @@ -53,6 +53,7 @@ class StackedPanelCollection : public PanelCollection, virtual bool CanShowMinimizeButton(const Panel* panel) const OVERRIDE; virtual bool CanShowRestoreButton(const Panel* panel) const OVERRIDE; virtual bool IsPanelMinimized(const Panel* panel) const OVERRIDE; + virtual bool UsesAlwaysOnTopPanels() const OVERRIDE; virtual void SavePanelPlacement(Panel* panel) OVERRIDE; virtual void RestorePanelToSavedPlacement() OVERRIDE; virtual void DiscardSavedPanelPlacement() OVERRIDE; diff --git a/chrome/browser/ui/views/panels/panel_view.cc b/chrome/browser/ui/views/panels/panel_view.cc index 911b6e0..122ce6e 100644 --- a/chrome/browser/ui/views/panels/panel_view.cc +++ b/chrome/browser/ui/views/panels/panel_view.cc @@ -225,24 +225,23 @@ panel::CornerStyle NativePanelTestingWin::GetWindowCornerStyle() const { } // namespace // static -NativePanel* Panel::CreateNativePanel(Panel* panel, const gfx::Rect& bounds) { - return new PanelView(panel, bounds); +NativePanel* Panel::CreateNativePanel(Panel* panel, + const gfx::Rect& bounds, + bool always_on_top) { + return new PanelView(panel, bounds, always_on_top); } // The panel window has to be created as always-on-top. We cannot create it // as non-always-on-top and then change it to always-on-top because Windows // system might deny making a window always-on-top if the application is not -// a foreground application. In addition, we do not know if the panel should -// be created as always-on-top at its creation time. To solve this issue, -// always_on_top_ is default to true because we can always change from -// always-on-top to not always-on-top but not the other way around. -PanelView::PanelView(Panel* panel, const gfx::Rect& bounds) +// a foreground application. +PanelView::PanelView(Panel* panel, const gfx::Rect& bounds, bool always_on_top) : panel_(panel), bounds_(bounds), window_(NULL), window_closed_(false), web_view_(NULL), - always_on_top_(true), + always_on_top_(always_on_top), focused_(false), user_resizing_(false), #if defined(OS_WIN) @@ -257,7 +256,7 @@ PanelView::PanelView(Panel* panel, const gfx::Rect& bounds) views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW); params.delegate = this; params.remove_standard_frame = true; - params.keep_on_top = true; + params.keep_on_top = always_on_top; params.bounds = bounds; window_->Init(params); window_->set_frame_type(views::Widget::FRAME_TYPE_FORCE_CUSTOM); diff --git a/chrome/browser/ui/views/panels/panel_view.h b/chrome/browser/ui/views/panels/panel_view.h index fb6f275..508ace3 100644 --- a/chrome/browser/ui/views/panels/panel_view.h +++ b/chrome/browser/ui/views/panels/panel_view.h @@ -37,7 +37,7 @@ class PanelView : public NativePanel, // The size of inside area used for mouse resizing. static const int kResizeInsideBoundsSize = 5; - PanelView(Panel* panel, const gfx::Rect& bounds); + PanelView(Panel* panel, const gfx::Rect& bounds, bool always_on_top); virtual ~PanelView(); // Overridden from NativePanel: |