Fix leaks by providing a target destruction notification to the EventHandler, which gives it the opportunity to clean itself up.
http://crbug.com/147756
[email protected]
Review URL: https://chromiumcodereview.appspot.com/10916230
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@156227 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/ash/root_window_controller.cc b/ash/root_window_controller.cc
index ef8df72..e9aff8b 100644
--- a/ash/root_window_controller.cc
+++ b/ash/root_window_controller.cc
@@ -128,161 +128,6 @@
container->SetProperty(internal::kUsesScreenCoordinatesKey, true);
}
-// Creates each of the special window containers that holds windows of various
-// types in the shell UI.
-void CreateContainersInRootWindow(aura::RootWindow* root_window) {
- // These containers are just used by PowerButtonController to animate groups
- // of containers simultaneously without messing up the current transformations
- // on those containers. These are direct children of the root window; all of
- // the other containers are their children.
- // Desktop and lock screen background containers are not part of the
- // lock animation so they are not included in those animate groups.
- // When screen is locked desktop background is moved to lock screen background
- // container (moved back on unlock). We want to make sure that there's an
- // opaque layer occluding the non-lock-screen layers.
-
- CreateContainer(internal::kShellWindowId_SystemBackgroundContainer,
- "SystemBackgroundContainer", root_window);
-
- aura::Window* desktop_background_containers = CreateContainer(
- internal::kShellWindowId_DesktopBackgroundContainer,
- "DesktopBackgroundContainer",
- root_window);
- SetChildWindowVisibilityChangesAnimated(desktop_background_containers);
-
- aura::Window* non_lock_screen_containers = CreateContainer(
- internal::kShellWindowId_NonLockScreenContainersContainer,
- "NonLockScreenContainersContainer",
- root_window);
-
- aura::Window* lock_background_containers = CreateContainer(
- internal::kShellWindowId_LockScreenBackgroundContainer,
- "LockScreenBackgroundContainer",
- root_window);
- SetChildWindowVisibilityChangesAnimated(lock_background_containers);
-
- aura::Window* lock_screen_containers = CreateContainer(
- internal::kShellWindowId_LockScreenContainersContainer,
- "LockScreenContainersContainer",
- root_window);
- aura::Window* lock_screen_related_containers = CreateContainer(
- internal::kShellWindowId_LockScreenRelatedContainersContainer,
- "LockScreenRelatedContainersContainer",
- root_window);
-
- CreateContainer(internal::kShellWindowId_UnparentedControlContainer,
- "UnparentedControlContainer",
- non_lock_screen_containers);
-
- aura::Window* default_container = CreateContainer(
- internal::kShellWindowId_DefaultContainer,
- "DefaultContainer",
- non_lock_screen_containers);
- if (!internal::WorkspaceController::IsWorkspace2Enabled()) {
- default_container->AddPreTargetHandler(
- new ToplevelWindowEventHandler(default_container));
- }
- SetChildWindowVisibilityChangesAnimated(default_container);
- SetUsesScreenCoordinates(default_container);
-
- aura::Window* always_on_top_container = CreateContainer(
- internal::kShellWindowId_AlwaysOnTopContainer,
- "AlwaysOnTopContainer",
- non_lock_screen_containers);
- always_on_top_container->AddPreTargetHandler(
- new ToplevelWindowEventHandler(always_on_top_container));
- SetChildWindowVisibilityChangesAnimated(always_on_top_container);
- SetUsesScreenCoordinates(always_on_top_container);
-
- aura::Window* panel_container = CreateContainer(
- internal::kShellWindowId_PanelContainer,
- "PanelContainer",
- non_lock_screen_containers);
- SetUsesScreenCoordinates(panel_container);
-
- aura::Window* launcher_container =
- CreateContainer(internal::kShellWindowId_LauncherContainer,
- "LauncherContainer",
- non_lock_screen_containers);
- SetUsesScreenCoordinates(launcher_container);
-
- CreateContainer(internal::kShellWindowId_AppListContainer,
- "AppListContainer",
- non_lock_screen_containers);
-
- aura::Window* modal_container = CreateContainer(
- internal::kShellWindowId_SystemModalContainer,
- "SystemModalContainer",
- non_lock_screen_containers);
- modal_container->AddPreTargetHandler(
- new ToplevelWindowEventHandler(modal_container));
- modal_container->SetLayoutManager(
- new internal::SystemModalContainerLayoutManager(modal_container));
- SetChildWindowVisibilityChangesAnimated(modal_container);
- SetUsesScreenCoordinates(modal_container);
-
- aura::Window* input_method_container = CreateContainer(
- internal::kShellWindowId_InputMethodContainer,
- "InputMethodContainer",
- non_lock_screen_containers);
- SetUsesScreenCoordinates(input_method_container);
-
- // TODO(beng): Figure out if we can make this use
- // SystemModalContainerEventFilter instead of stops_event_propagation.
- aura::Window* lock_container = CreateContainer(
- internal::kShellWindowId_LockScreenContainer,
- "LockScreenContainer",
- lock_screen_containers);
- lock_container->SetLayoutManager(
- new internal::BaseLayoutManager(root_window));
- SetUsesScreenCoordinates(lock_container);
- // TODO(beng): stopsevents
-
- aura::Window* lock_modal_container = CreateContainer(
- internal::kShellWindowId_LockSystemModalContainer,
- "LockSystemModalContainer",
- lock_screen_containers);
- lock_modal_container->AddPreTargetHandler(
- new ToplevelWindowEventHandler(lock_modal_container));
- lock_modal_container->SetLayoutManager(
- new internal::SystemModalContainerLayoutManager(lock_modal_container));
- SetChildWindowVisibilityChangesAnimated(lock_modal_container);
- SetUsesScreenCoordinates(lock_modal_container);
-
- aura::Window* status_container =
- CreateContainer(internal::kShellWindowId_StatusContainer,
- "StatusContainer",
- lock_screen_related_containers);
- SetUsesScreenCoordinates(status_container);
-
- aura::Window* settings_bubble_container = CreateContainer(
- internal::kShellWindowId_SettingBubbleContainer,
- "SettingBubbleContainer",
- lock_screen_related_containers);
- SetChildWindowVisibilityChangesAnimated(settings_bubble_container);
- SetUsesScreenCoordinates(settings_bubble_container);
-
- aura::Window* menu_container = CreateContainer(
- internal::kShellWindowId_MenuContainer,
- "MenuContainer",
- lock_screen_related_containers);
- SetChildWindowVisibilityChangesAnimated(menu_container);
- SetUsesScreenCoordinates(menu_container);
-
- aura::Window* drag_drop_container = CreateContainer(
- internal::kShellWindowId_DragImageAndTooltipContainer,
- "DragImageAndTooltipContainer",
- lock_screen_related_containers);
- SetChildWindowVisibilityChangesAnimated(drag_drop_container);
- SetUsesScreenCoordinates(drag_drop_container);
-
- aura::Window* overlay_container = CreateContainer(
- internal::kShellWindowId_OverlayContainer,
- "OverlayContainer",
- lock_screen_related_containers);
- SetUsesScreenCoordinates(overlay_container);
-}
-
} // namespace
namespace internal {
@@ -395,5 +240,168 @@
}
}
+////////////////////////////////////////////////////////////////////////////////
+// RootWindowController, private:
+
+void RootWindowController::CreateContainersInRootWindow(
+ aura::RootWindow* root_window) {
+ // These containers are just used by PowerButtonController to animate groups
+ // of containers simultaneously without messing up the current transformations
+ // on those containers. These are direct children of the root window; all of
+ // the other containers are their children.
+ // Desktop and lock screen background containers are not part of the
+ // lock animation so they are not included in those animate groups.
+ // When screen is locked desktop background is moved to lock screen background
+ // container (moved back on unlock). We want to make sure that there's an
+ // opaque layer occluding the non-lock-screen layers.
+
+ CreateContainer(internal::kShellWindowId_SystemBackgroundContainer,
+ "SystemBackgroundContainer", root_window);
+
+ aura::Window* desktop_background_containers = CreateContainer(
+ internal::kShellWindowId_DesktopBackgroundContainer,
+ "DesktopBackgroundContainer",
+ root_window);
+ SetChildWindowVisibilityChangesAnimated(desktop_background_containers);
+
+ aura::Window* non_lock_screen_containers = CreateContainer(
+ internal::kShellWindowId_NonLockScreenContainersContainer,
+ "NonLockScreenContainersContainer",
+ root_window);
+
+ aura::Window* lock_background_containers = CreateContainer(
+ internal::kShellWindowId_LockScreenBackgroundContainer,
+ "LockScreenBackgroundContainer",
+ root_window);
+ SetChildWindowVisibilityChangesAnimated(lock_background_containers);
+
+ aura::Window* lock_screen_containers = CreateContainer(
+ internal::kShellWindowId_LockScreenContainersContainer,
+ "LockScreenContainersContainer",
+ root_window);
+ aura::Window* lock_screen_related_containers = CreateContainer(
+ internal::kShellWindowId_LockScreenRelatedContainersContainer,
+ "LockScreenRelatedContainersContainer",
+ root_window);
+
+ CreateContainer(internal::kShellWindowId_UnparentedControlContainer,
+ "UnparentedControlContainer",
+ non_lock_screen_containers);
+
+ aura::Window* default_container = CreateContainer(
+ internal::kShellWindowId_DefaultContainer,
+ "DefaultContainer",
+ non_lock_screen_containers);
+ if (!internal::WorkspaceController::IsWorkspace2Enabled()) {
+ default_container_handler_.reset(
+ new ToplevelWindowEventHandler(default_container));
+ default_container->AddPreTargetHandler(default_container_handler_.get());
+ }
+ SetChildWindowVisibilityChangesAnimated(default_container);
+ SetUsesScreenCoordinates(default_container);
+
+ aura::Window* always_on_top_container = CreateContainer(
+ internal::kShellWindowId_AlwaysOnTopContainer,
+ "AlwaysOnTopContainer",
+ non_lock_screen_containers);
+ always_on_top_container_handler_.reset(
+ new ToplevelWindowEventHandler(always_on_top_container));
+ always_on_top_container->AddPreTargetHandler(
+ always_on_top_container_handler_.get());
+ SetChildWindowVisibilityChangesAnimated(always_on_top_container);
+ SetUsesScreenCoordinates(always_on_top_container);
+
+ aura::Window* panel_container = CreateContainer(
+ internal::kShellWindowId_PanelContainer,
+ "PanelContainer",
+ non_lock_screen_containers);
+ SetUsesScreenCoordinates(panel_container);
+
+ aura::Window* launcher_container =
+ CreateContainer(internal::kShellWindowId_LauncherContainer,
+ "LauncherContainer",
+ non_lock_screen_containers);
+ SetUsesScreenCoordinates(launcher_container);
+
+ CreateContainer(internal::kShellWindowId_AppListContainer,
+ "AppListContainer",
+ non_lock_screen_containers);
+
+ aura::Window* modal_container = CreateContainer(
+ internal::kShellWindowId_SystemModalContainer,
+ "SystemModalContainer",
+ non_lock_screen_containers);
+ modal_container_handler_.reset(
+ new ToplevelWindowEventHandler(modal_container));
+ modal_container->AddPreTargetHandler(modal_container_handler_.get());
+ modal_container->SetLayoutManager(
+ new internal::SystemModalContainerLayoutManager(modal_container));
+ SetChildWindowVisibilityChangesAnimated(modal_container);
+ SetUsesScreenCoordinates(modal_container);
+
+ aura::Window* input_method_container = CreateContainer(
+ internal::kShellWindowId_InputMethodContainer,
+ "InputMethodContainer",
+ non_lock_screen_containers);
+ SetUsesScreenCoordinates(input_method_container);
+
+ // TODO(beng): Figure out if we can make this use
+ // SystemModalContainerEventFilter instead of stops_event_propagation.
+ aura::Window* lock_container = CreateContainer(
+ internal::kShellWindowId_LockScreenContainer,
+ "LockScreenContainer",
+ lock_screen_containers);
+ lock_container->SetLayoutManager(
+ new internal::BaseLayoutManager(root_window));
+ SetUsesScreenCoordinates(lock_container);
+ // TODO(beng): stopsevents
+
+ aura::Window* lock_modal_container = CreateContainer(
+ internal::kShellWindowId_LockSystemModalContainer,
+ "LockSystemModalContainer",
+ lock_screen_containers);
+ lock_modal_container_handler_.reset(
+ new ToplevelWindowEventHandler(lock_modal_container));
+ lock_modal_container->AddPreTargetHandler(
+ lock_modal_container_handler_.get());
+ lock_modal_container->SetLayoutManager(
+ new internal::SystemModalContainerLayoutManager(lock_modal_container));
+ SetChildWindowVisibilityChangesAnimated(lock_modal_container);
+ SetUsesScreenCoordinates(lock_modal_container);
+
+ aura::Window* status_container =
+ CreateContainer(internal::kShellWindowId_StatusContainer,
+ "StatusContainer",
+ lock_screen_related_containers);
+ SetUsesScreenCoordinates(status_container);
+
+ aura::Window* settings_bubble_container = CreateContainer(
+ internal::kShellWindowId_SettingBubbleContainer,
+ "SettingBubbleContainer",
+ lock_screen_related_containers);
+ SetChildWindowVisibilityChangesAnimated(settings_bubble_container);
+ SetUsesScreenCoordinates(settings_bubble_container);
+
+ aura::Window* menu_container = CreateContainer(
+ internal::kShellWindowId_MenuContainer,
+ "MenuContainer",
+ lock_screen_related_containers);
+ SetChildWindowVisibilityChangesAnimated(menu_container);
+ SetUsesScreenCoordinates(menu_container);
+
+ aura::Window* drag_drop_container = CreateContainer(
+ internal::kShellWindowId_DragImageAndTooltipContainer,
+ "DragImageAndTooltipContainer",
+ lock_screen_related_containers);
+ SetChildWindowVisibilityChangesAnimated(drag_drop_container);
+ SetUsesScreenCoordinates(drag_drop_container);
+
+ aura::Window* overlay_container = CreateContainer(
+ internal::kShellWindowId_OverlayContainer,
+ "OverlayContainer",
+ lock_screen_related_containers);
+ SetUsesScreenCoordinates(overlay_container);
+}
+
} // namespace internal
} // namespace ash
diff --git a/ash/root_window_controller.h b/ash/root_window_controller.h
index c17d85a..27f396d1 100644
--- a/ash/root_window_controller.h
+++ b/ash/root_window_controller.h
@@ -21,6 +21,7 @@
} // namespace aura
namespace ash {
+class ToplevelWindowEventHandler;
namespace internal {
class EventClientImpl;
@@ -75,6 +76,10 @@
void MoveWindowsTo(aura::RootWindow* dest);
private:
+ // Creates each of the special window containers that holds windows of various
+ // types in the shell UI.
+ void CreateContainersInRootWindow(aura::RootWindow* root_window);
+
scoped_ptr<aura::RootWindow> root_window_;
internal::RootWindowLayoutManager* root_window_layout_;
@@ -83,6 +88,12 @@
scoped_ptr<internal::ScreenDimmer> screen_dimmer_;
scoped_ptr<internal::WorkspaceController> workspace_controller_;
+ // We need to own event handlers for various containers.
+ scoped_ptr<ToplevelWindowEventHandler> default_container_handler_;
+ scoped_ptr<ToplevelWindowEventHandler> always_on_top_container_handler_;
+ scoped_ptr<ToplevelWindowEventHandler> modal_container_handler_;
+ scoped_ptr<ToplevelWindowEventHandler> lock_modal_container_handler_;
+
DISALLOW_COPY_AND_ASSIGN(RootWindowController);
};
diff --git a/ash/wm/workspace/workspace2.cc b/ash/wm/workspace/workspace2.cc
index a145521..8e1ac5e 100644
--- a/ash/wm/workspace/workspace2.cc
+++ b/ash/wm/workspace/workspace2.cc
@@ -31,7 +31,7 @@
window_->layer()->SetMasksToBounds(true);
window_->Hide();
window_->SetParent(parent);
- window_->AddPreTargetHandler(event_handler_);
+ window_->AddPreTargetHandler(event_handler_.get());
window_->SetProperty(internal::kUsesScreenCoordinatesKey, true);
}
@@ -47,7 +47,6 @@
window_->SetEventFilter(NULL);
aura::Window* window = window_;
window_ = NULL;
- event_handler_ = NULL;
return window;
}
diff --git a/ash/wm/workspace/workspace2.h b/ash/wm/workspace/workspace2.h
index 6fbfe3b..92e8e725 100644
--- a/ash/wm/workspace/workspace2.h
+++ b/ash/wm/workspace/workspace2.h
@@ -9,6 +9,7 @@
#include "ash/ash_export.h"
#include "base/basictypes.h"
+#include "base/memory/scoped_ptr.h"
namespace aura {
class Window;
@@ -60,8 +61,7 @@
// Our Window, owned by |parent| passed to the constructor.
aura::Window* window_;
- // Owned by |window_|.
- WorkspaceEventHandler* event_handler_;
+ scoped_ptr<WorkspaceEventHandler> event_handler_;
DISALLOW_COPY_AND_ASSIGN(Workspace2);
};
diff --git a/tools/heapcheck/suppressions.txt b/tools/heapcheck/suppressions.txt
index f0bc1917..f8b1d0f 100644
--- a/tools/heapcheck/suppressions.txt
+++ b/tools/heapcheck/suppressions.txt
@@ -1605,24 +1605,6 @@
fun:PluginPrefsTest_UnifiedPepperFlashState_Test::TestBody
}
{
- bug_147756_a
- Heapcheck:Leak
- fun:Workspace2
- fun:ash::internal::WorkspaceManager2::CreateWorkspace
- fun:WorkspaceManager2
- fun:WorkspaceController
- fun:ash::internal::RootWindowController::InitLayoutManagers
- fun:ash::Shell::InitRootWindowController
- fun:ash::Shell::Init
-}
-{
- bug_147756_b
- Heapcheck:Leak
- fun:ash::::CreateContainersInRootWindow
- fun:ash::internal::RootWindowController::CreateContainers
- fun:ash::Shell::Init
-}
-{
bug_148589
Heapcheck:Leak
fun:ui::Clipboard::GetForCurrentThread
diff --git a/tools/valgrind/memcheck/suppressions.txt b/tools/valgrind/memcheck/suppressions.txt
index cc82235..c7fce3a3 100644
--- a/tools/valgrind/memcheck/suppressions.txt
+++ b/tools/valgrind/memcheck/suppressions.txt
@@ -5987,26 +5987,6 @@
fun:_ZN11PluginPrefs30EnablePluginIfPossibleCallbackEbRK8FilePathRKN4base8CallbackIFvbEEEP12PluginFinder
}
{
- bug_147756_a
- Memcheck:Leak
- fun:_Znw*
- fun:_ZN3ash8internal10Workspace2C1EPNS0_17WorkspaceManager2EPN4aura6WindowEb
- fun:_ZN3ash8internal17WorkspaceManager215CreateWorkspaceEb
- fun:_ZN3ash8internal17WorkspaceManager2C1EPN4aura6WindowE
- fun:_ZN3ash8internal19WorkspaceControllerC1EPN4aura6WindowE
- fun:_ZN3ash8internal20RootWindowController18InitLayoutManagersEv
- fun:_ZN3ash5Shell24InitRootWindowControllerEPNS_8internal20RootWindowControllerE
- fun:_ZN3ash5Shell4InitEv
-}
-{
- bug_147756_b
- Memcheck:Leak
- fun:_Znw*
- fun:_ZN3ash*CreateContainersInRootWindowEPN4aura10RootWindowE
- fun:_ZN3ash8internal20RootWindowController16CreateContainersEv
- fun:_ZN3ash5Shell4InitEv
-}
-{
bug_148475
Memcheck:Uninitialized
...