Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(132)

Side by Side Diff: views/widget/widget.cc

Issue 7748036: Restoring a session should restore window minimization state on Windows (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase Created 9 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « views/widget/widget.h ('k') | views/widget/widget_delegate.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "views/widget/widget.h" 5 #include "views/widget/widget.h"
6 6
7 #include "base/logging.h" 7 #include "base/logging.h"
8 #include "base/message_loop.h" 8 #include "base/message_loop.h"
9 #include "base/utf_string_conversions.h" 9 #include "base/utf_string_conversions.h"
10 #include "ui/base/l10n/l10n_font_util.h" 10 #include "ui/base/l10n/l10n_font_util.h"
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
102 delegate(NULL), 102 delegate(NULL),
103 child(false), 103 child(false),
104 transient(false), 104 transient(false),
105 transparent(false), 105 transparent(false),
106 accept_events(true), 106 accept_events(true),
107 can_activate(true), 107 can_activate(true),
108 keep_on_top(false), 108 keep_on_top(false),
109 ownership(NATIVE_WIDGET_OWNS_WIDGET), 109 ownership(NATIVE_WIDGET_OWNS_WIDGET),
110 mirror_origin_in_rtl(false), 110 mirror_origin_in_rtl(false),
111 has_dropshadow(false), 111 has_dropshadow(false),
112 maximize(false), 112 show_state(ui::SHOW_STATE_DEFAULT),
113 double_buffer(false), 113 double_buffer(false),
114 parent(NULL), 114 parent(NULL),
115 parent_widget(NULL), 115 parent_widget(NULL),
116 native_widget(NULL), 116 native_widget(NULL),
117 top_level(false) { 117 top_level(false) {
118 } 118 }
119 119
120 Widget::InitParams::InitParams(Type type) 120 Widget::InitParams::InitParams(Type type)
121 : type(type), 121 : type(type),
122 delegate(NULL), 122 delegate(NULL),
123 child(type == TYPE_CONTROL), 123 child(type == TYPE_CONTROL),
124 transient(type == TYPE_POPUP || type == TYPE_MENU), 124 transient(type == TYPE_POPUP || type == TYPE_MENU),
125 transparent(false), 125 transparent(false),
126 accept_events(true), 126 accept_events(true),
127 can_activate(type != TYPE_POPUP && type != TYPE_MENU), 127 can_activate(type != TYPE_POPUP && type != TYPE_MENU),
128 keep_on_top(type == TYPE_MENU), 128 keep_on_top(type == TYPE_MENU),
129 ownership(NATIVE_WIDGET_OWNS_WIDGET), 129 ownership(NATIVE_WIDGET_OWNS_WIDGET),
130 mirror_origin_in_rtl(false), 130 mirror_origin_in_rtl(false),
131 has_dropshadow(false), 131 has_dropshadow(false),
132 maximize(false), 132 show_state(ui::SHOW_STATE_DEFAULT),
133 double_buffer(false), 133 double_buffer(false),
134 parent(NULL), 134 parent(NULL),
135 parent_widget(NULL), 135 parent_widget(NULL),
136 native_widget(NULL), 136 native_widget(NULL),
137 top_level(false) { 137 top_level(false) {
138 } 138 }
139 139
140 //////////////////////////////////////////////////////////////////////////////// 140 ////////////////////////////////////////////////////////////////////////////////
141 // Widget, public: 141 // Widget, public:
142 142
143 // static 143 // static
144 Widget::InitParams Widget::WindowInitParams() { 144 Widget::InitParams Widget::WindowInitParams() {
145 return InitParams(InitParams::TYPE_WINDOW); 145 return InitParams(InitParams::TYPE_WINDOW);
146 } 146 }
147 147
148 Widget::Widget() 148 Widget::Widget()
149 : is_mouse_button_pressed_(false), 149 : is_mouse_button_pressed_(false),
150 last_mouse_event_was_move_(false), 150 last_mouse_event_was_move_(false),
151 native_widget_(NULL), 151 native_widget_(NULL),
152 widget_delegate_(NULL), 152 widget_delegate_(NULL),
153 non_client_view_(NULL), 153 non_client_view_(NULL),
154 dragged_view_(NULL), 154 dragged_view_(NULL),
155 event_stack_(), 155 event_stack_(),
156 ownership_(InitParams::NATIVE_WIDGET_OWNS_WIDGET), 156 ownership_(InitParams::NATIVE_WIDGET_OWNS_WIDGET),
157 is_secondary_widget_(true), 157 is_secondary_widget_(true),
158 frame_type_(FRAME_TYPE_DEFAULT), 158 frame_type_(FRAME_TYPE_DEFAULT),
159 disable_inactive_rendering_(false), 159 disable_inactive_rendering_(false),
160 widget_closed_(false), 160 widget_closed_(false),
161 saved_maximized_state_(false), 161 saved_show_state_(ui::SHOW_STATE_DEFAULT),
162 minimum_size_(100, 100), 162 minimum_size_(100, 100),
163 focus_on_creation_(true), 163 focus_on_creation_(true),
164 is_top_level_(false) { 164 is_top_level_(false),
165 native_widget_initialized_(false) {
165 } 166 }
166 167
167 Widget::~Widget() { 168 Widget::~Widget() {
168 while (!event_stack_.empty()) { 169 while (!event_stack_.empty()) {
169 event_stack_.top()->reset(); 170 event_stack_.top()->reset();
170 event_stack_.pop(); 171 event_stack_.pop();
171 } 172 }
172 173
173 DestroyRootView(); 174 DestroyRootView();
174 if (ownership_ == InitParams::WIDGET_OWNS_NATIVE_WIDGET) 175 if (ownership_ == InitParams::WIDGET_OWNS_NATIVE_WIDGET)
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
304 } 305 }
305 native_widget_->InitNativeWidget(params); 306 native_widget_->InitNativeWidget(params);
306 if (params.type == InitParams::TYPE_WINDOW) { 307 if (params.type == InitParams::TYPE_WINDOW) {
307 non_client_view_ = new NonClientView; 308 non_client_view_ = new NonClientView;
308 non_client_view_->SetFrameView(CreateNonClientFrameView()); 309 non_client_view_->SetFrameView(CreateNonClientFrameView());
309 // Create the ClientView, add it to the NonClientView and add the 310 // Create the ClientView, add it to the NonClientView and add the
310 // NonClientView to the RootView. This will cause everything to be parented. 311 // NonClientView to the RootView. This will cause everything to be parented.
311 non_client_view_->set_client_view(widget_delegate_->CreateClientView(this)); 312 non_client_view_->set_client_view(widget_delegate_->CreateClientView(this));
312 SetContentsView(non_client_view_); 313 SetContentsView(non_client_view_);
313 SetInitialBounds(params.bounds); 314 SetInitialBounds(params.bounds);
314 if (params.maximize) 315 if (params.show_state == ui::SHOW_STATE_MAXIMIZED)
315 Maximize(); 316 Maximize();
317 else if (params.show_state == ui::SHOW_STATE_MINIMIZED)
318 Minimize();
316 UpdateWindowTitle(); 319 UpdateWindowTitle();
317 } 320 }
321 native_widget_initialized_ = true;
318 } 322 }
319 323
320 // Unconverted methods (see header) -------------------------------------------- 324 // Unconverted methods (see header) --------------------------------------------
321 325
322 gfx::NativeView Widget::GetNativeView() const { 326 gfx::NativeView Widget::GetNativeView() const {
323 return native_widget_->GetNativeView(); 327 return native_widget_->GetNativeView();
324 } 328 }
325 329
326 gfx::NativeWindow Widget::GetNativeWindow() const { 330 gfx::NativeWindow Widget::GetNativeWindow() const {
327 return native_widget_->GetNativeWindow(); 331 return native_widget_->GetNativeWindow();
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
439 // It appears we can hit this code path if you close a modal dialog then 443 // It appears we can hit this code path if you close a modal dialog then
440 // close the last browser before the destructor is hit, which triggers 444 // close the last browser before the destructor is hit, which triggers
441 // invoking Close again. 445 // invoking Close again.
442 return; 446 return;
443 } 447 }
444 448
445 bool can_close = true; 449 bool can_close = true;
446 if (non_client_view_) 450 if (non_client_view_)
447 can_close = non_client_view_->CanClose(); 451 can_close = non_client_view_->CanClose();
448 if (can_close) { 452 if (can_close) {
449 SaveWindowPosition(); 453 SaveWindowPlacement();
450 454
451 // During tear-down the top-level focus manager becomes unavailable to 455 // During tear-down the top-level focus manager becomes unavailable to
452 // GTK tabbed panes and their children, so normal deregistration via 456 // GTK tabbed panes and their children, so normal deregistration via
453 // |FormManager::ViewRemoved()| calls are fouled. We clear focus here 457 // |FormManager::ViewRemoved()| calls are fouled. We clear focus here
454 // to avoid these redundant steps and to avoid accessing deleted views 458 // to avoid these redundant steps and to avoid accessing deleted views
455 // that may have been in focus. 459 // that may have been in focus.
456 if (is_top_level() && focus_manager_.get()) 460 if (is_top_level() && focus_manager_.get())
457 focus_manager_->SetFocusedView(NULL); 461 focus_manager_->SetFocusedView(NULL);
458 462
459 native_widget_->Close(); 463 native_widget_->Close();
460 widget_closed_ = true; 464 widget_closed_ = true;
461 } 465 }
462 } 466 }
463 467
464 void Widget::CloseNow() { 468 void Widget::CloseNow() {
465 native_widget_->CloseNow(); 469 native_widget_->CloseNow();
466 } 470 }
467 471
468 void Widget::EnableClose(bool enable) { 472 void Widget::EnableClose(bool enable) {
469 if (non_client_view_) 473 if (non_client_view_)
470 non_client_view_->EnableClose(enable); 474 non_client_view_->EnableClose(enable);
471 native_widget_->EnableClose(enable); 475 native_widget_->EnableClose(enable);
472 } 476 }
473 477
474 void Widget::Show() { 478 void Widget::Show() {
475 if (non_client_view_) { 479 if (non_client_view_) {
476 if (saved_maximized_state_ && !initial_restored_bounds_.IsEmpty()) { 480 if (saved_show_state_ == ui::SHOW_STATE_MAXIMIZED &&
481 !initial_restored_bounds_.IsEmpty()) {
477 native_widget_->ShowMaximizedWithBounds(initial_restored_bounds_); 482 native_widget_->ShowMaximizedWithBounds(initial_restored_bounds_);
478 } else { 483 } else {
479 native_widget_->ShowWithState(saved_maximized_state_ ? 484 native_widget_->ShowWithWindowState(saved_show_state_);
480 internal::NativeWidgetPrivate::SHOW_MAXIMIZED :
481 internal::NativeWidgetPrivate::SHOW_RESTORED);
482 } 485 }
483 // |saved_maximized_state_| only applies the first time the window is shown. 486 // |saved_show_state_| only applies the first time the window is shown.
484 // If we don't reset the value the window will be shown maximized every time 487 // If we don't reset the value the window may be shown maximized every time
485 // it is subsequently shown after being hidden. 488 // it is subsequently shown after being hidden.
486 saved_maximized_state_ = false; 489 saved_show_state_ = ui::SHOW_STATE_NORMAL;
487 } else { 490 } else {
488 native_widget_->Show(); 491 native_widget_->Show();
489 } 492 }
490 } 493 }
491 494
492 void Widget::Hide() { 495 void Widget::Hide() {
493 native_widget_->Hide(); 496 native_widget_->Hide();
494 } 497 }
495 498
496 void Widget::ShowInactive() { 499 void Widget::ShowInactive() {
497 // If this gets called with saved_maximized_state_ == true, call SetBounds() 500 // If this gets called with saved_show_state_ == ui::SHOW_STATE_MAXIMIZED,
498 // with the restored bounds to set the correct size. This normally should 501 // call SetBounds()with the restored bounds to set the correct size. This
499 // not happen, but if it does we should avoid showing unsized windows. 502 // normally should not happen, but if it does we should avoid showing unsized
500 if (saved_maximized_state_ && !initial_restored_bounds_.IsEmpty()) { 503 // windows.
504 if (saved_show_state_ == ui::SHOW_STATE_MAXIMIZED &&
505 !initial_restored_bounds_.IsEmpty()) {
501 SetBounds(initial_restored_bounds_); 506 SetBounds(initial_restored_bounds_);
502 saved_maximized_state_ = false; 507 saved_show_state_ = ui::SHOW_STATE_NORMAL;
503 } 508 }
504 native_widget_->ShowWithState(internal::NativeWidgetPrivate::SHOW_INACTIVE); 509 native_widget_->ShowWithWindowState(ui::SHOW_STATE_INACTIVE);
505 } 510 }
506 511
507 void Widget::Activate() { 512 void Widget::Activate() {
508 native_widget_->Activate(); 513 native_widget_->Activate();
509 } 514 }
510 515
511 void Widget::Deactivate() { 516 void Widget::Deactivate() {
512 native_widget_->Deactivate(); 517 native_widget_->Deactivate();
513 } 518 }
514 519
(...skipping 303 matching lines...) Expand 10 before | Expand all | Expand 10 after
818 } 823 }
819 824
820 void Widget::EnableInactiveRendering() { 825 void Widget::EnableInactiveRendering() {
821 disable_inactive_rendering_ = false; 826 disable_inactive_rendering_ = false;
822 if (non_client_view_) 827 if (non_client_view_)
823 non_client_view_->DisableInactiveRendering(false); 828 non_client_view_->DisableInactiveRendering(false);
824 } 829 }
825 830
826 void Widget::OnNativeWidgetActivationChanged(bool active) { 831 void Widget::OnNativeWidgetActivationChanged(bool active) {
827 if (!active) { 832 if (!active) {
828 SaveWindowPosition(); 833 SaveWindowPlacement();
829 834
830 // Close any open menus. 835 // Close any open menus.
831 MenuController* menu_controller = MenuController::GetActiveInstance(); 836 MenuController* menu_controller = MenuController::GetActiveInstance();
832 if (menu_controller) 837 if (menu_controller)
833 menu_controller->OnWidgetActivationChanged(); 838 menu_controller->OnWidgetActivationChanged();
834 } 839 }
835 840
836 FOR_EACH_OBSERVER(Observer, observers_, 841 FOR_EACH_OBSERVER(Observer, observers_,
837 OnWidgetActivationChanged(this, active)); 842 OnWidgetActivationChanged(this, active));
838 } 843 }
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
879 widget_delegate_->DeleteDelegate(); 884 widget_delegate_->DeleteDelegate();
880 widget_delegate_ = NULL; 885 widget_delegate_ = NULL;
881 } 886 }
882 887
883 gfx::Size Widget::GetMinimumSize() { 888 gfx::Size Widget::GetMinimumSize() {
884 return non_client_view_ ? non_client_view_->GetMinimumSize() : gfx::Size(); 889 return non_client_view_ ? non_client_view_->GetMinimumSize() : gfx::Size();
885 } 890 }
886 891
887 void Widget::OnNativeWidgetSizeChanged(const gfx::Size& new_size) { 892 void Widget::OnNativeWidgetSizeChanged(const gfx::Size& new_size) {
888 root_view_->SetSize(new_size); 893 root_view_->SetSize(new_size);
894
895 // Size changed notifications can fire prior to full initialization
896 // i.e. during session restore. Avoid saving session state during these
897 // startup procedures.
898 if (native_widget_initialized_)
899 SaveWindowPlacement();
889 } 900 }
890 901
891 void Widget::OnNativeWidgetBeginUserBoundsChange() { 902 void Widget::OnNativeWidgetBeginUserBoundsChange() {
892 widget_delegate_->OnWindowBeginUserBoundsChange(); 903 widget_delegate_->OnWindowBeginUserBoundsChange();
893 } 904 }
894 905
895 void Widget::OnNativeWidgetEndUserBoundsChange() { 906 void Widget::OnNativeWidgetEndUserBoundsChange() {
896 widget_delegate_->OnWindowEndUserBoundsChange(); 907 widget_delegate_->OnWindowEndUserBoundsChange();
897 } 908 }
898 909
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
1048 //////////////////////////////////////////////////////////////////////////////// 1059 ////////////////////////////////////////////////////////////////////////////////
1049 // Widget, private: 1060 // Widget, private:
1050 1061
1051 // static 1062 // static
1052 ui::Compositor*(*Widget::compositor_factory_)() = NULL; 1063 ui::Compositor*(*Widget::compositor_factory_)() = NULL;
1053 1064
1054 bool Widget::ShouldReleaseCaptureOnMouseReleased() const { 1065 bool Widget::ShouldReleaseCaptureOnMouseReleased() const {
1055 return true; 1066 return true;
1056 } 1067 }
1057 1068
1058 void Widget::SaveWindowPosition() { 1069 void Widget::SaveWindowPlacement() {
1059 // The window delegate does the actual saving for us. It seems like (judging 1070 // The window delegate does the actual saving for us. It seems like (judging
1060 // by go/crash) that in some circumstances we can end up here after 1071 // by go/crash) that in some circumstances we can end up here after
1061 // WM_DESTROY, at which point the window delegate is likely gone. So just 1072 // WM_DESTROY, at which point the window delegate is likely gone. So just
1062 // bail. 1073 // bail.
1063 if (!widget_delegate_) 1074 if (!widget_delegate_)
1064 return; 1075 return;
1065 1076
1066 bool maximized = false; 1077 ui::WindowShowState show_state = ui::SHOW_STATE_NORMAL;
1067 gfx::Rect bounds; 1078 gfx::Rect bounds;
1068 native_widget_->GetWindowBoundsAndMaximizedState(&bounds, &maximized); 1079 native_widget_->GetWindowPlacement(&bounds, &show_state);
1069 widget_delegate_->SaveWindowPlacement(bounds, maximized); 1080 widget_delegate_->SaveWindowPlacement(bounds, show_state);
1070 } 1081 }
1071 1082
1072 void Widget::SetInitialBounds(const gfx::Rect& bounds) { 1083 void Widget::SetInitialBounds(const gfx::Rect& bounds) {
1073 if (!non_client_view_) 1084 if (!non_client_view_)
1074 return; 1085 return;
1075 1086
1076 gfx::Rect saved_bounds; 1087 gfx::Rect saved_bounds;
1077 if (GetSavedBounds(&saved_bounds, &saved_maximized_state_)) { 1088 if (GetSavedWindowPlacement(&saved_bounds, &saved_show_state_)) {
1078 if (saved_maximized_state_) { 1089 if (saved_show_state_ == ui::SHOW_STATE_MAXIMIZED) {
1079 // If we're going to maximize, wait until Show is invoked to set the 1090 // If we're going to maximize, wait until Show is invoked to set the
1080 // bounds. That way we avoid a noticable resize. 1091 // bounds. That way we avoid a noticable resize.
1081 initial_restored_bounds_ = saved_bounds; 1092 initial_restored_bounds_ = saved_bounds;
1082 } else { 1093 } else {
1083 SetBounds(saved_bounds); 1094 SetBounds(saved_bounds);
1084 } 1095 }
1085 } else { 1096 } else {
1086 if (bounds.IsEmpty()) { 1097 if (bounds.IsEmpty()) {
1087 // No initial bounds supplied, so size the window to its content and 1098 // No initial bounds supplied, so size the window to its content and
1088 // center over its parent. 1099 // center over its parent.
1089 native_widget_->CenterWindow(non_client_view_->GetPreferredSize()); 1100 native_widget_->CenterWindow(non_client_view_->GetPreferredSize());
1090 } else { 1101 } else {
1091 // Use the supplied initial bounds. 1102 // Use the supplied initial bounds.
1092 SetBoundsConstrained(bounds, NULL); 1103 SetBoundsConstrained(bounds, NULL);
1093 } 1104 }
1094 } 1105 }
1095 } 1106 }
1096 1107
1097 bool Widget::GetSavedBounds(gfx::Rect* bounds, bool* maximize) { 1108 bool Widget::GetSavedWindowPlacement(gfx::Rect* bounds,
1109 ui::WindowShowState* show_state) {
1098 // First we obtain the window's saved show-style and store it. We need to do 1110 // First we obtain the window's saved show-style and store it. We need to do
1099 // this here, rather than in Show() because by the time Show() is called, 1111 // this here, rather than in Show() because by the time Show() is called,
1100 // the window's size will have been reset (below) and the saved maximized 1112 // the window's size will have been reset (below) and the saved maximized
1101 // state will have been lost. Sadly there's no way to tell on Windows when 1113 // state will have been lost. Sadly there's no way to tell on Windows when
1102 // a window is restored from maximized state, so we can't more accurately 1114 // a window is restored from maximized state, so we can't more accurately
1103 // track maximized state independently of sizing information. 1115 // track maximized state independently of sizing information.
1104 widget_delegate_->GetSavedMaximizedState(maximize);
1105 1116
1106 // Restore the window's placement from the controller. 1117 // Restore the window's placement from the controller.
1107 if (widget_delegate_->GetSavedWindowBounds(bounds)) { 1118 if (widget_delegate_->GetSavedWindowPlacement(bounds, show_state)) {
1108 if (!widget_delegate_->ShouldRestoreWindowSize()) { 1119 if (!widget_delegate_->ShouldRestoreWindowSize()) {
1109 bounds->set_size(non_client_view_->GetPreferredSize()); 1120 bounds->set_size(non_client_view_->GetPreferredSize());
1110 } else { 1121 } else {
1111 // Make sure the bounds are at least the minimum size. 1122 // Make sure the bounds are at least the minimum size.
1112 if (bounds->width() < minimum_size_.width()) 1123 if (bounds->width() < minimum_size_.width())
1113 bounds->set_width(minimum_size_.width()); 1124 bounds->set_width(minimum_size_.width());
1114 1125
1115 if (bounds->height() < minimum_size_.height()) 1126 if (bounds->height() < minimum_size_.height())
1116 bounds->set_height(minimum_size_.height()); 1127 bounds->set_height(minimum_size_.height());
1117 } 1128 }
(...skipping 16 matching lines...) Expand all
1134 1145
1135 //////////////////////////////////////////////////////////////////////////////// 1146 ////////////////////////////////////////////////////////////////////////////////
1136 // internal::NativeWidgetPrivate, NativeWidget implementation: 1147 // internal::NativeWidgetPrivate, NativeWidget implementation:
1137 1148
1138 internal::NativeWidgetPrivate* NativeWidgetPrivate::AsNativeWidgetPrivate() { 1149 internal::NativeWidgetPrivate* NativeWidgetPrivate::AsNativeWidgetPrivate() {
1139 return this; 1150 return this;
1140 } 1151 }
1141 1152
1142 } // namespace internal 1153 } // namespace internal
1143 } // namespace views 1154 } // namespace views
OLDNEW
« no previous file with comments | « views/widget/widget.h ('k') | views/widget/widget_delegate.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698