diff options
Diffstat (limited to 'chrome')
-rw-r--r-- | chrome/browser/automation/automation_window_tracker.h | 2 | ||||
-rw-r--r-- | chrome/browser/browser_list.cc | 8 | ||||
-rw-r--r-- | chrome/browser/browser_list.h | 3 | ||||
-rw-r--r-- | chrome/browser/views/frame/browser_view.cc | 7 | ||||
-rw-r--r-- | chrome/common/common.vcproj | 4 | ||||
-rw-r--r-- | chrome/common/hwnd_notification_source.h (renamed from chrome/views/widget/hwnd_notification_source.h) | 6 | ||||
-rw-r--r-- | chrome/common/notification_type.h | 4 | ||||
-rw-r--r-- | chrome/common/temp_scaffolding_stubs.cc | 5 | ||||
-rw-r--r-- | chrome/views/controls/native_control.cc | 1 | ||||
-rw-r--r-- | chrome/views/focus/focus_manager.cc | 20 | ||||
-rw-r--r-- | chrome/views/focus/focus_manager.h | 11 | ||||
-rw-r--r-- | chrome/views/focus/view_storage.cc | 41 | ||||
-rw-r--r-- | chrome/views/focus/view_storage.h | 16 | ||||
-rw-r--r-- | chrome/views/view_unittest.cc | 74 | ||||
-rw-r--r-- | chrome/views/views.vcproj | 4 | ||||
-rw-r--r-- | chrome/views/widget/root_view.cc | 25 | ||||
-rw-r--r-- | chrome/views/widget/widget_win.cc | 8 | ||||
-rw-r--r-- | chrome/views/window/window.h | 12 | ||||
-rw-r--r-- | chrome/views/window/window_win.cc | 54 | ||||
-rw-r--r-- | chrome/views/window/window_win.h | 17 |
20 files changed, 143 insertions, 179 deletions
diff --git a/chrome/browser/automation/automation_window_tracker.h b/chrome/browser/automation/automation_window_tracker.h index 1b9aff8..effa61e 100644 --- a/chrome/browser/automation/automation_window_tracker.h +++ b/chrome/browser/automation/automation_window_tracker.h @@ -13,7 +13,7 @@ // Since HWNDs aren't pointers, we can't have NativeWindow // be directly a pointer and so must explicitly declare the Source types // for it. -#include "chrome/views/widget/hwnd_notification_source.h" +#include "chrome/common/hwnd_notification_source.h" #elif defined(OS_LINUX) || defined(OS_MACOSX) // But on Linux and Mac, it is a pointer so this definition suffices. template<> diff --git a/chrome/browser/browser_list.cc b/chrome/browser/browser_list.cc index 3b6ee8b..034bba6 100644 --- a/chrome/browser/browser_list.cc +++ b/chrome/browser/browser_list.cc @@ -67,12 +67,8 @@ void BrowserList::RemoveBrowser(Browser* browser) { // If the last Browser object was destroyed, make sure we try to close any // remaining dependent windows too. - if (browsers_.empty()) { - NotificationService::current()->Notify( - NotificationType::ALL_APPWINDOWS_CLOSED, - NotificationService::AllSources(), - NotificationService::NoDetails()); - } + if (browsers_.empty()) + AllBrowsersClosed(); g_browser_process->ReleaseModule(); } diff --git a/chrome/browser/browser_list.h b/chrome/browser/browser_list.h index c73ac2e..f167fdc 100644 --- a/chrome/browser/browser_list.h +++ b/chrome/browser/browser_list.h @@ -115,6 +115,9 @@ class BrowserList { // Returns true if at least one off the record session is active. static bool IsOffTheRecordSessionActive(); + // Called when the last browser is closed. + static void AllBrowsersClosed(); + private: // Helper method to remove a browser instance from a list of browsers static void RemoveBrowserFrom(Browser* browser, list_type* browser_list); diff --git a/chrome/browser/views/frame/browser_view.cc b/chrome/browser/views/frame/browser_view.cc index 4d861f0..694c109 100644 --- a/chrome/browser/views/frame/browser_view.cc +++ b/chrome/browser/views/frame/browser_view.cc @@ -50,6 +50,7 @@ #include "chrome/browser/tab_contents/tab_contents_view.h" #include "chrome/browser/window_sizer.h" #include "chrome/common/chrome_switches.h" +#include "chrome/common/hwnd_notification_source.h" #include "chrome/common/notification_service.h" #include "chrome/common/pref_names.h" #include "chrome/common/pref_service.h" @@ -57,7 +58,6 @@ #include "chrome/views/controls/scrollbar/native_scroll_bar.h" #include "chrome/views/fill_layout.h" #include "chrome/views/view.h" -#include "chrome/views/widget/hwnd_notification_source.h" #include "chrome/views/widget/root_view.h" #include "chrome/views/window/non_client_view.h" #include "chrome/views/window/window_win.h" @@ -1666,3 +1666,8 @@ BrowserWindow* BrowserWindow::CreateBrowserWindow(Browser* browser) { FindBar* BrowserWindow::CreateFindBar(Browser* browser) { return new FindBarWin(static_cast<BrowserView*>(browser->window())); } + +// static +void BrowserList::AllBrowsersClosed() { + views::Window::CloseAllSecondaryWindows(); +} diff --git a/chrome/common/common.vcproj b/chrome/common/common.vcproj index 90b15d8..4c2d021 100644 --- a/chrome/common/common.vcproj +++ b/chrome/common/common.vcproj @@ -458,6 +458,10 @@ > </File> <File + RelativePath=".\hwnd_notification_source.h" + > + </File> + <File RelativePath=".\important_file_writer.cc" > </File> diff --git a/chrome/views/widget/hwnd_notification_source.h b/chrome/common/hwnd_notification_source.h index 602ae44..63df703 100644 --- a/chrome/views/widget/hwnd_notification_source.h +++ b/chrome/common/hwnd_notification_source.h @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_VIEWS_WIDGET_HWND_NOTIFICATION_SOURCE_H_ -#define CHROME_VIEWS_WIDGET_HWND_NOTIFICATION_SOURCE_H_ +#ifndef CHROME_COMMON_HWND_NOTIFICATION_SOURCE_H_ +#define CHROME_COMMON_HWND_NOTIFICATION_SOURCE_H_ #include "chrome/common/notification_source.h" @@ -21,4 +21,4 @@ class Source<HWND> : public NotificationSource { HWND ptr() const { return static_cast<HWND>(ptr_); } }; -#endif // #define CHROME_VIEWS_WIDGET_HWND_NOTIFICATION_SOURCE_H_ +#endif // #define CHROME_COMMON_HWND_NOTIFICATION_SOURCE_H_ diff --git a/chrome/common/notification_type.h b/chrome/common/notification_type.h index 1f67ec3..82d62e0 100644 --- a/chrome/common/notification_type.h +++ b/chrome/common/notification_type.h @@ -184,10 +184,6 @@ class NotificationType { // details are passed. ALL_APPWINDOWS_CLOSED, - // Indicates a new top window has been created. The source is the - // WindowWin. - WINDOW_CREATED, - // Indicates that a top window has been closed. The source is the HWND // that was closed, no details are expected. WINDOW_CLOSED, diff --git a/chrome/common/temp_scaffolding_stubs.cc b/chrome/common/temp_scaffolding_stubs.cc index b4d87c8..9706e26 100644 --- a/chrome/common/temp_scaffolding_stubs.cc +++ b/chrome/common/temp_scaffolding_stubs.cc @@ -312,3 +312,8 @@ void HungRendererDialog::HideForTabContents(TabContents*) { void HungRendererDialog::ShowForTabContents(TabContents*) { NOTIMPLEMENTED(); } + +void BrowserList::AllBrowsersClosed() { + // TODO(port): Close any dependent windows if necessary when the last browser + // window is closed. +} diff --git a/chrome/views/controls/native_control.cc b/chrome/views/controls/native_control.cc index 84a3226..bf40711 100644 --- a/chrome/views/controls/native_control.cc +++ b/chrome/views/controls/native_control.cc @@ -12,7 +12,6 @@ #include "app/l10n_util_win.h" #include "base/logging.h" #include "base/win_util.h" -#include "chrome/common/notification_service.h" #include "chrome/views/background.h" #include "chrome/views/border.h" #include "chrome/views/controls/hwnd_view.h" diff --git a/chrome/views/focus/focus_manager.cc b/chrome/views/focus/focus_manager.cc index 031cb0a..9e477e9 100644 --- a/chrome/views/focus/focus_manager.cc +++ b/chrome/views/focus/focus_manager.cc @@ -8,7 +8,6 @@ #include "base/logging.h" #include "base/win_util.h" #include "chrome/browser/renderer_host/render_widget_host_view_win.h" -#include "chrome/common/notification_service.h" #include "chrome/views/accelerator.h" #include "chrome/views/focus/focus_manager.h" #include "chrome/views/focus/view_storage.h" @@ -102,13 +101,6 @@ FocusManager* FocusManager::CreateFocusManager(HWND window, FocusManager* focus_manager = new FocusManager(window, root_view); SetProp(window, kFocusManagerKey, focus_manager); - // We register for view removed notifications so we can make sure we don't - // keep references to invalidated views. - NotificationService::current()->AddObserver( - focus_manager, - NotificationType::VIEW_REMOVED, - NotificationService::AllSources()); - return focus_manager; } @@ -212,11 +204,6 @@ bool FocusManager::OnNCDestroy(HWND window) { // We are the top window. DCHECK(GetProp(window, kFocusManagerKey)); - // Unregister notifications. - NotificationService::current()->RemoveObserver( - this, - NotificationType::VIEW_REMOVED, - NotificationService::AllSources()); // Make sure this is called on the window that was set with the // FocusManager. @@ -685,11 +672,8 @@ AcceleratorTarget* FocusManager::GetTargetForAccelerator( return NULL; } -void FocusManager::Observe(NotificationType type, - const NotificationSource& source, - const NotificationDetails& details) { - DCHECK(type == NotificationType::VIEW_REMOVED); - if (focused_view_ && Source<View>(focused_view_) == source) +void FocusManager::ViewRemoved(View* parent, View* removed) { + if (focused_view_ && focused_view_ == removed) focused_view_ = NULL; } diff --git a/chrome/views/focus/focus_manager.h b/chrome/views/focus/focus_manager.h index 190385b..4a32c0d 100644 --- a/chrome/views/focus/focus_manager.h +++ b/chrome/views/focus/focus_manager.h @@ -13,7 +13,6 @@ #include <vector> #include <map> -#include "chrome/common/notification_observer.h" #include "chrome/views/accelerator.h" // The FocusManager class is used to handle focus traversal, store/restore @@ -152,7 +151,7 @@ class FocusChangeListener { virtual void FocusWillChange(View* focused_before, View* focused_now) = 0; }; -class FocusManager : public NotificationObserver { +class FocusManager { public: #if defined(OS_WIN) // Creates a FocusManager for the specified window. Top level windows @@ -264,10 +263,10 @@ class FocusManager : public NotificationObserver { // Returns true if an accelerator was activated. bool ProcessAccelerator(const Accelerator& accelerator); - // NotificationObserver method. - void Observe(NotificationType type, - const NotificationSource& source, - const NotificationDetails& details); + // Called by a RootView when a view within its hierarchy is removed from its + // parent. This will only be called by a RootView in a hierarchy of Widgets + // that this FocusManager is attached to the parent Widget of. + void ViewRemoved(View* parent, View* removed); void AddKeystrokeListener(KeystrokeListener* listener); void RemoveKeystrokeListener(KeystrokeListener* listener); diff --git a/chrome/views/focus/view_storage.cc b/chrome/views/focus/view_storage.cc index 1a8324c..7299809 100644 --- a/chrome/views/focus/view_storage.cc +++ b/chrome/views/focus/view_storage.cc @@ -6,8 +6,8 @@ #include <algorithm> +#include "base/logging.h" #include "base/stl_util-inl.h" -#include "chrome/common/notification_service.h" namespace views { @@ -38,8 +38,6 @@ ViewStorage* ViewStorage::GetSharedInstance() { } ViewStorage::ViewStorage() : view_storage_next_id_(0) { - NotificationService::current()->AddObserver( - this, NotificationType::VIEW_REMOVED, NotificationService::AllSources()); } ViewStorage::~ViewStorage() { @@ -54,7 +52,7 @@ int ViewStorage::CreateStorageID() { return view_storage_next_id_++; } -void ViewStorage::StoreView(int storage_id, View* view) { +int ViewStorage::StoreView(int storage_id, View* view) { DCHECK(view); std::map<int, ViewLocationInfo*>::iterator iter = id_to_view_location_.find(storage_id); @@ -92,6 +90,7 @@ void ViewStorage::StoreView(int storage_id, View* view) { ids = id_iter->second; } ids->push_back(storage_id); + return storage_id; } View* ViewStorage::RetrieveView(int storage_id) { @@ -126,6 +125,21 @@ void ViewStorage::RemoveView(int storage_id) { EraseView(storage_id, false); } +void ViewStorage::ViewRemoved(View* parent, View* removed) { + // Let's first retrieve the ids for that view. + std::map<View*, std::vector<int>*>::iterator ids_iter = + view_to_ids_.find(removed); + + if (ids_iter == view_to_ids_.end()) { + // That view is not in the view storage. + return; + } + + std::vector<int>* ids = ids_iter->second; + DCHECK(!ids->empty()); + EraseView((*ids)[0], true); +} + void ViewStorage::EraseView(int storage_id, bool remove_all_ids) { // Remove the view from id_to_view_location_. std::map<int, ViewLocationInfo*>::iterator location_iter = @@ -166,23 +180,4 @@ void ViewStorage::EraseView(int storage_id, bool remove_all_ids) { } } -void ViewStorage::Observe(NotificationType type, - const NotificationSource& source, - const NotificationDetails& details) { - DCHECK(type == NotificationType::VIEW_REMOVED); - - // Let's first retrieve the ids for that view. - std::map<View*, std::vector<int>*>::iterator ids_iter = - view_to_ids_.find(Source<View>(source).ptr()); - - if (ids_iter == view_to_ids_.end()) { - // That view is not in the view storage. - return; - } - - std::vector<int>* ids = ids_iter->second; - DCHECK(!ids->empty()); - EraseView((*ids)[0], true); -} - } // namespace views diff --git a/chrome/views/focus/view_storage.h b/chrome/views/focus/view_storage.h index cb0cb67..8ba9c9a 100644 --- a/chrome/views/focus/view_storage.h +++ b/chrome/views/focus/view_storage.h @@ -6,7 +6,6 @@ #define CHROME_VIEWS_FOCUS_VIEW_STORAGE_H_ #include "base/singleton.h" -#include "chrome/common/notification_observer.h" #include "chrome/views/view.h" // This class is a simple storage place for storing/retrieving views. It is @@ -26,7 +25,7 @@ namespace views { struct ViewLocationInfo; -class ViewStorage : public NotificationObserver { +class ViewStorage { public: // Returns the global ViewStorage instance. // It is guaranted to be non NULL. @@ -35,8 +34,9 @@ class ViewStorage : public NotificationObserver { // Returns a unique storage id that can be used to store/retrieve views. int CreateStorageID(); - // Associates |view| with the specified |storage_id|. - void StoreView(int storage_id, View* view); + // Associates |view| with the specified |storage_id|. Returns the + // |storage_id|. + int StoreView(int storage_id, View* view); // Returns the view associated with |storage_id| if any, NULL otherwise. View* RetrieveView(int storage_id); @@ -44,17 +44,15 @@ class ViewStorage : public NotificationObserver { // Removes the view associated with |storage_id| if any. void RemoveView(int storage_id); + // Notifies the ViewStorage that a view was removed from its parent somewhere. + void ViewRemoved(View* parent, View* removed); + private: friend struct DefaultSingletonTraits<ViewStorage>; ViewStorage(); ~ViewStorage(); - // NotificationObserver method. - void Observe(NotificationType type, - const NotificationSource& source, - const NotificationDetails& details); - // Removes the view associated with |storage_id|. If |remove_all_ids| is true, // all other mapping pointing to the same view are removed as well. void EraseView(int storage_id, bool remove_all_ids); diff --git a/chrome/views/view_unittest.cc b/chrome/views/view_unittest.cc index da8c6ff..5b4f4ee 100644 --- a/chrome/views/view_unittest.cc +++ b/chrome/views/view_unittest.cc @@ -16,6 +16,7 @@ #include "chrome/views/controls/scroll_view.h" #include "chrome/views/controls/text_field.h" #include "chrome/views/event.h" +#include "chrome/views/focus/view_storage.h" #include "chrome/views/view.h" #include "chrome/views/widget/root_view.h" #include "chrome/views/widget/widget_win.h" @@ -430,96 +431,77 @@ TEST_F(ViewTest, DISABLED_Painting) { window.DestroyWindow(); } */ -typedef std::vector<View*> ViewList; - -class RemoveViewObserver : public NotificationObserver { -public: - RemoveViewObserver() { } - - void Observe(NotificationType type, const NotificationSource& source, - const NotificationDetails& details) { - ASSERT_TRUE(type == NotificationType::VIEW_REMOVED); - removed_views_.push_back(Source<views::View>(source).ptr()); - } - - bool WasRemoved(views::View* view) { - return std::find(removed_views_.begin(), removed_views_.end(), view) != - removed_views_.end(); - } - - ViewList removed_views_; - -}; TEST_F(ViewTest, RemoveNotification) { - scoped_ptr<RemoveViewObserver> observer(new RemoveViewObserver); - - NotificationService::current()->AddObserver( - observer.get(), - NotificationType::VIEW_REMOVED, - NotificationService::AllSources()); - + views::ViewStorage* vs = views::ViewStorage::GetSharedInstance(); views::WidgetWin* window = new views::WidgetWin; views::RootView* root_view = window->GetRootView(); View* v1 = new View; + int s1 = vs->StoreView(vs->CreateStorageID(), v1); root_view->AddChildView(v1); View* v11 = new View; + int s11 = vs->StoreView(vs->CreateStorageID(), v11); v1->AddChildView(v11); View* v111 = new View; + int s111 = vs->StoreView(vs->CreateStorageID(), v111); v11->AddChildView(v111); View* v112 = new View; + int s112 = vs->StoreView(vs->CreateStorageID(), v112); v11->AddChildView(v112); View* v113 = new View; + int s113 = vs->StoreView(vs->CreateStorageID(), v113); v11->AddChildView(v113); View* v1131 = new View; + int s1131 = vs->StoreView(vs->CreateStorageID(), v1131); v113->AddChildView(v1131); View* v12 = new View; + int s12 = vs->StoreView(vs->CreateStorageID(), v12); v1->AddChildView(v12); View* v2 = new View; + int s2 = vs->StoreView(vs->CreateStorageID(), v2); root_view->AddChildView(v2); View* v21 = new View; + int s21 = vs->StoreView(vs->CreateStorageID(), v21); v2->AddChildView(v21); View* v211 = new View; + int s211 = vs->StoreView(vs->CreateStorageID(), v211); v21->AddChildView(v211); // Try removing a leaf view. v21->RemoveChildView(v211); - EXPECT_EQ(1, observer->removed_views_.size()); - EXPECT_TRUE(observer->WasRemoved(v211)); + EXPECT_EQ(NULL, vs->RetrieveView(s211)); delete v211; // We won't use this one anymore. // Now try removing a view with a hierarchy of depth 1. - observer->removed_views_.clear(); v11->RemoveChildView(v113); - EXPECT_EQ(observer->removed_views_.size(), 2); - EXPECT_TRUE(observer->WasRemoved(v113) && observer->WasRemoved(v1131)); + EXPECT_EQ(NULL, vs->RetrieveView(s113)); + EXPECT_EQ(NULL, vs->RetrieveView(s1131)); delete v113; // We won't use this one anymore. // Now remove even more. - observer->removed_views_.clear(); root_view->RemoveChildView(v1); - EXPECT_EQ(observer->removed_views_.size(), 5); - EXPECT_TRUE(observer->WasRemoved(v1) && - observer->WasRemoved(v11) && observer->WasRemoved(v12) && - observer->WasRemoved(v111) && observer->WasRemoved(v112)); + EXPECT_EQ(NULL, vs->RetrieveView(s1)); + EXPECT_EQ(NULL, vs->RetrieveView(s11)); + EXPECT_EQ(NULL, vs->RetrieveView(s12)); + EXPECT_EQ(NULL, vs->RetrieveView(s111)); + EXPECT_EQ(NULL, vs->RetrieveView(s112)); // Put v1 back for more tests. root_view->AddChildView(v1); - observer->removed_views_.clear(); + vs->StoreView(s1, v1); // Now delete the root view (deleting the window will trigger a delete of the // RootView) and make sure we are notified that the views were removed. delete window; - EXPECT_EQ(observer->removed_views_.size(), 7); - EXPECT_TRUE(observer->WasRemoved(v1) && observer->WasRemoved(v2) && - observer->WasRemoved(v11) && observer->WasRemoved(v12) && - observer->WasRemoved(v21) && - observer->WasRemoved(v111) && observer->WasRemoved(v112)); - - NotificationService::current()->RemoveObserver(observer.get(), - NotificationType::VIEW_REMOVED, NotificationService::AllSources()); + EXPECT_EQ(NULL, vs->RetrieveView(s1)); + EXPECT_EQ(NULL, vs->RetrieveView(s12)); + EXPECT_EQ(NULL, vs->RetrieveView(s11)); + EXPECT_EQ(NULL, vs->RetrieveView(s12)); + EXPECT_EQ(NULL, vs->RetrieveView(s21)); + EXPECT_EQ(NULL, vs->RetrieveView(s111)); + EXPECT_EQ(NULL, vs->RetrieveView(s112)); } namespace { diff --git a/chrome/views/views.vcproj b/chrome/views/views.vcproj index 8e5d2fe..f972022 100644 --- a/chrome/views/views.vcproj +++ b/chrome/views/views.vcproj @@ -197,10 +197,6 @@ > </File> <File - RelativePath=".\widget\hwnd_notification_source.h" - > - </File> - <File RelativePath=".\widget\root_view.cc" > <FileConfiguration diff --git a/chrome/views/widget/root_view.cc b/chrome/views/widget/root_view.cc index bd57fe4..07680e6 100644 --- a/chrome/views/widget/root_view.cc +++ b/chrome/views/widget/root_view.cc @@ -13,11 +13,12 @@ #endif #include "base/logging.h" #include "base/message_loop.h" -#include "chrome/common/notification_service.h" #if defined(OS_WIN) +#include "chrome/views/focus/view_storage.h" #include "chrome/views/widget/root_view_drop_target.h" #endif #include "chrome/views/widget/widget.h" +#include "chrome/views/window/window.h" namespace views { @@ -261,10 +262,24 @@ void RootView::ViewHierarchyChanged(bool is_add, View* parent, View* child) { if (default_keyboard_handler_ == child) { default_keyboard_handler_ = NULL; } - NotificationService::current()->Notify( - NotificationType::VIEW_REMOVED, - Source<View>(child), - Details<View>(parent)); + + // For a given widget hierarchy, focus is tracked by a FocusManager attached + // to our nearest enclosing Window. <-- Important Assumption! + // We may not have access to our window if this function is called as a + // result of teardown during the deletion of the RootView and its hierarchy, + // so we don't bother notifying the FocusManager in that case because it + // will have already been destroyed (the Widget that contains us is + // NCDESTROY'ed which in turn destroys the focus manager _before_ the + // RootView is deleted.) +#if defined(OS_WIN) + Window* window = GetWindow(); + if (window) { + FocusManager* focus_manager = + FocusManager::GetFocusManager(window->GetNativeWindow()); + focus_manager->ViewRemoved(parent, child); + } + ViewStorage::GetSharedInstance()->ViewRemoved(parent, child); +#endif } } diff --git a/chrome/views/widget/widget_win.cc b/chrome/views/widget/widget_win.cc index 0bb3e78..5ee065a 100644 --- a/chrome/views/widget/widget_win.cc +++ b/chrome/views/widget/widget_win.cc @@ -9,14 +9,12 @@ #include "base/string_util.h" #include "base/win_util.h" #include "chrome/app/chrome_dll_resource.h" -#include "chrome/common/notification_service.h" #include "chrome/common/win_util.h" #include "chrome/views/accessibility/view_accessibility.h" #include "chrome/views/controls/native_control_win.h" #include "chrome/views/fill_layout.h" #include "chrome/views/focus/focus_util_win.h" #include "chrome/views/widget/aero_tooltip_manager.h" -#include "chrome/views/widget/hwnd_notification_source.h" #include "chrome/views/widget/root_view.h" #include "chrome/views/window/window_win.h" @@ -467,12 +465,6 @@ void WidgetWin::OnCaptureChanged(HWND hwnd) { } void WidgetWin::OnClose() { - // WARNING: this method is NOT called for all WidgetWins. If you need to do - // cleanup code before WidgetWin is destroyed, put it in OnDestroy. - NotificationService::current()->Notify( - NotificationType::WINDOW_CLOSED, Source<HWND>(hwnd_), - NotificationService::NoDetails()); - Close(); } diff --git a/chrome/views/window/window.h b/chrome/views/window/window.h index fe820da..819f31c 100644 --- a/chrome/views/window/window.h +++ b/chrome/views/window/window.h @@ -39,6 +39,11 @@ class Window { static gfx::Size GetLocalizedContentsSize(int col_resource_id, int row_resource_id); + // Closes all windows that aren't identified as "app windows" via + // IsAppWindow. Called during application shutdown when the last "app window" + // is closed. + static void CloseAllSecondaryWindows(); + // Retrieves the window's bounds, including its frame. virtual gfx::Rect GetBounds() const = 0; @@ -47,7 +52,7 @@ class Window { // Sizes and/or places the window to the specified bounds, size or position. virtual void SetBounds(const gfx::Rect& bounds) = 0; - + // As above, except the window is inserted after |other_window| in the window // Z-order. If this window is not yet visible, other_window's monitor is used // as the constraining rectangle, rather than this window's monitor. @@ -85,6 +90,11 @@ class Window { virtual void SetFullscreen(bool fullscreen) = 0; virtual bool IsFullscreen() const = 0; + // Returns true if the Window is considered to be an "app window" - i.e. + // any window which when it is the last of its type closed causes the + // application to exit. + virtual bool IsAppWindow() const { return false; } + // Toggles the enable state for the Close button (and the Close menu item in // the system menu). virtual void EnableClose(bool enable) = 0; diff --git a/chrome/views/window/window_win.cc b/chrome/views/window/window_win.cc index 7b0c528..73be950 100644 --- a/chrome/views/window/window_win.cc +++ b/chrome/views/window/window_win.cc @@ -14,7 +14,6 @@ #include "app/resource_bundle.h" #include "base/win_util.h" #include "chrome/app/chrome_dll_resource.h" -#include "chrome/common/notification_service.h" #include "chrome/common/win_util.h" #include "chrome/views/widget/root_view.h" #include "chrome/views/window/client_view.h" @@ -429,19 +428,6 @@ gfx::NativeWindow WindowWin::GetNativeWindow() const { return GetNativeView(); } -//////////////////////////////////////////////////////////////////////////////// -// WindowWin, NotificationObserver implementation: - -void WindowWin::Observe(NotificationType type, - const NotificationSource& source, - const NotificationDetails& details) { - // This window is closed when the last app window is closed. - DCHECK(type == NotificationType::ALL_APPWINDOWS_CLOSED); - // Only registered as an observer when we're not an app window. - // XXX DCHECK(!IsAppWindow()); - Close(); -} - /////////////////////////////////////////////////////////////////////////////// // WindowWin, protected: @@ -507,20 +493,7 @@ void WindowWin::Init(HWND parent, const gfx::Rect& bounds) { GetMonitorAndRects(bounds.ToRECT(), &last_monitor_, &last_monitor_rect_, &last_work_area_); - - if (!IsAppWindow()) { - notification_registrar_.Add( - this, - NotificationType::ALL_APPWINDOWS_CLOSED, - NotificationService::AllSources()); - } - ResetWindowRegion(false); - - NotificationService::current()->Notify( - NotificationType::WINDOW_CREATED, - Source<WindowWin>(this), - NotificationService::NoDetails()); } void WindowWin::SizeWindowToDefault() { @@ -1443,4 +1416,31 @@ void WindowWin::InitClass() { } } +namespace { +// static +static BOOL CALLBACK WindowCallbackProc(HWND hwnd, LPARAM lParam) { + WidgetWin* widget = reinterpret_cast<WidgetWin*>( + win_util::GetWindowUserData(hwnd)); + if (!widget) + return TRUE; + + // If the toplevel HWND is a Window, close it if it's identified as a + // secondary window. + Window* window = widget->GetWindow(); + if (window) { + if (!window->IsAppWindow()) + window->Close(); + } else { + // If it's not a Window, then close it anyway since it probably is + // secondary. + widget->Close(); + } + return TRUE; +} +} // namespace + +void Window::CloseAllSecondaryWindows() { + EnumThreadWindows(GetCurrentThreadId(), WindowCallbackProc, 0); +} + } // namespace views diff --git a/chrome/views/window/window_win.h b/chrome/views/window/window_win.h index 239e17e..749ae94 100644 --- a/chrome/views/window/window_win.h +++ b/chrome/views/window/window_win.h @@ -5,7 +5,6 @@ #ifndef CHROME_VIEWS_WINDOW_WINDOW_WIN_H__ #define CHROME_VIEWS_WINDOW_WINDOW_WIN_H__ -#include "chrome/common/notification_registrar.h" #include "chrome/views/widget/widget_win.h" #include "chrome/views/window/client_view.h" #include "chrome/views/window/non_client_view.h" @@ -30,8 +29,7 @@ class WindowDelegate; // /////////////////////////////////////////////////////////////////////////////// class WindowWin : public WidgetWin, - public Window, - public NotificationObserver { + public Window { public: virtual ~WindowWin(); @@ -91,11 +89,6 @@ class WindowWin : public WidgetWin, virtual ClientView* GetClientView() const; virtual gfx::NativeWindow GetNativeWindow() const; - // NotificationObserver overrides: - virtual void Observe(NotificationType type, - const NotificationSource& source, - const NotificationDetails& details); - protected: friend Window; @@ -111,11 +104,6 @@ class WindowWin : public WidgetWin, // Sizes the window to the default size specified by its ClientView. virtual void SizeWindowToDefault(); - // Returns true if the WindowWin is considered to be an "app window" - i.e. - // any window which when it is the last of its type closed causes the - // application to exit. - virtual bool IsAppWindow() const { return false; } - // Shows the system menu at the specified screen point. void RunSystemMenu(const gfx::Point& point); @@ -311,9 +299,6 @@ class WindowWin : public WidgetWin, HMONITOR last_monitor_; gfx::Rect last_monitor_rect_, last_work_area_; - // Hold onto notifications. - NotificationRegistrar notification_registrar_; - DISALLOW_COPY_AND_ASSIGN(WindowWin); }; |