Index: ash/wm/workspace/frame_maximize_button.cc |
diff --git a/ash/wm/workspace/frame_maximize_button.cc b/ash/wm/workspace/frame_maximize_button.cc |
index 89297c5d76be29b2e73ba657faa2e1a32055fc1e..b5360f1aa5f5df52f03c52675b197bd863e562cf 100644 |
--- a/ash/wm/workspace/frame_maximize_button.cc |
+++ b/ash/wm/workspace/frame_maximize_button.cc |
@@ -113,6 +113,9 @@ FrameMaximizeButton::FrameMaximizeButton(views::ButtonListener* listener, |
} |
FrameMaximizeButton::~FrameMaximizeButton() { |
+ // Before the window gets destroyed, the maximizer dialog needs to be shut |
+ // down since it would otherwise call into a deleted object. |
+ maximizer_.reset(); |
if (window_) |
OnWindowDestroying(window_); |
} |
@@ -151,13 +154,14 @@ void FrameMaximizeButton::SnapButtonHovered(SnapType type) { |
void FrameMaximizeButton::ExecuteSnapAndCloseMenu(SnapType snap_type) { |
DCHECK_NE(snap_type_, SNAP_NONE); |
- snap_type_ = snap_type; |
- Snap(); |
- // Remove any pending snap previews. |
- SnapButtonHovered(SNAP_NONE); |
- // At this point the operation has been performed and the menu should be |
- // closed - if not, it'll get now closed. |
+ Cancel(true); |
+ // Tell our menu to close. |
maximizer_.reset(); |
+ snap_type_ = snap_type; |
+ // Since Snap might destroy |this|, but the snap_sizer needs to be destroyed, |
+ // The ownership of the snap_sizer is taken now. |
+ scoped_ptr<SnapSizer> snap_sizer(snap_sizer_.release()); |
+ Snap(snap_sizer.get()); |
} |
void FrameMaximizeButton::DestroyMaximizeMenu() { |
@@ -321,7 +325,10 @@ bool FrameMaximizeButton::ProcessEndEvent(const views::LocatedEvent& event) { |
// BS_NORMAL during a drag. |
SchedulePaint(); |
phantom_window_.reset(); |
- Snap(); |
+ // Since Snap might destroy |this|, but the snap_sizer needs to be destroyed, |
+ // The ownership of the snap_sizer is taken now. |
+ scoped_ptr<SnapSizer> snap_sizer(snap_sizer_.release()); |
+ Snap(snap_sizer.get()); |
return true; |
} |
@@ -330,9 +337,9 @@ void FrameMaximizeButton::Cancel(bool keep_menu_open) { |
maximizer_.reset(); |
UninstallEventFilter(); |
is_snap_enabled_ = false; |
+ snap_sizer_.reset(); |
} |
phantom_window_.reset(); |
- snap_sizer_.reset(); |
snap_type_ = SNAP_NONE; |
update_timer_.Stop(); |
SchedulePaint(); |
@@ -394,7 +401,7 @@ void FrameMaximizeButton::UpdateSnap(const gfx::Point& location) { |
phantom_window_->set_phantom_below_window(maximizer_->GetBubbleWindow()); |
maximizer_->SetSnapType(snap_type_); |
} |
- phantom_window_->Show(ScreenBoundsForType(snap_type_)); |
+ phantom_window_->Show(ScreenBoundsForType(snap_type_, snap_sizer_.get())); |
} |
SnapType FrameMaximizeButton::SnapTypeForLocation( |
@@ -412,14 +419,17 @@ SnapType FrameMaximizeButton::SnapTypeForLocation( |
return !frame_->GetWidget()->IsMaximized() ? SNAP_MAXIMIZE : SNAP_RESTORE; |
} |
-gfx::Rect FrameMaximizeButton::ScreenBoundsForType(SnapType type) const { |
+gfx::Rect FrameMaximizeButton::ScreenBoundsForType( |
+ SnapType type, |
+ SnapSizer* snap_sizer) const { |
aura::Window* window = frame_->GetWidget()->GetNativeWindow(); |
switch (type) { |
case SNAP_LEFT: |
case SNAP_RIGHT: |
+ DCHECK(snap_sizer); |
return ScreenAsh::ConvertRectToScreen( |
frame_->GetWidget()->GetNativeView()->parent(), |
- snap_sizer_->target_bounds()); |
+ snap_sizer->target_bounds()); |
case SNAP_MAXIMIZE: |
return ScreenAsh::ConvertRectToScreen( |
window->parent(), |
@@ -453,16 +463,19 @@ gfx::Point FrameMaximizeButton::LocationForSnapSizer( |
return result; |
} |
-void FrameMaximizeButton::Snap() { |
+void FrameMaximizeButton::Snap(SnapSizer* snap_sizer) { |
switch (snap_type_) { |
case SNAP_LEFT: |
case SNAP_RIGHT: |
+ DCHECK(snap_sizer); |
if (frame_->GetWidget()->IsMaximized()) { |
ash::SetRestoreBoundsInScreen(frame_->GetWidget()->GetNativeWindow(), |
- ScreenBoundsForType(snap_type_)); |
+ ScreenBoundsForType(snap_type_, |
+ snap_sizer)); |
frame_->GetWidget()->Restore(); |
} else { |
- frame_->GetWidget()->SetBounds(ScreenBoundsForType(snap_type_)); |
+ frame_->GetWidget()->SetBounds(ScreenBoundsForType(snap_type_, |
+ snap_sizer)); |
} |
break; |
case SNAP_MAXIMIZE: |