From 5fe1b8b76c903a4f4e19d9ed52d7ad36c1a8752b Mon Sep 17 00:00:00 2001 From: "ben@chromium.org" Date: Wed, 9 Mar 2011 03:25:15 +0000 Subject: Consolidate window showing into Window base class. NativeWindow gets methods to update accessible state, title, Center and Show. BUG=72040 TEST=none Review URL: http://codereview.chromium.org/6647004 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@77421 0039d316-1c4b-4281-b951-d872f2087c98 --- views/window/native_window.h | 27 ++++ views/window/native_window_delegate.h | 7 +- views/window/window.cc | 96 ++++++++++++- views/window/window.h | 21 ++- views/window/window_delegate.h | 3 +- views/window/window_gtk.cc | 142 ++++++++----------- views/window/window_gtk.h | 21 +-- views/window/window_win.cc | 253 ++++++++++++---------------------- views/window/window_win.h | 48 ++----- 9 files changed, 313 insertions(+), 305 deletions(-) (limited to 'views/window') diff --git a/views/window/native_window.h b/views/window/native_window.h index 5347eab..30fb87a 100644 --- a/views/window/native_window.h +++ b/views/window/native_window.h @@ -6,6 +6,8 @@ #define VIEWS_WIDGET_NATIVE_WINDOW_H_ #pragma once +#include "views/accessibility/accessibility_types.h" + namespace views { //////////////////////////////////////////////////////////////////////////////// @@ -15,7 +17,32 @@ namespace views { // class NativeWindow { public: + enum ShowState { + SHOW_RESTORED, + SHOW_MAXIMIZED + }; + virtual ~NativeWindow() {} + + // Shows the window. + virtual void Show(ShowState state) = 0; + + // Makes the NativeWindow modal. + virtual void BecomeModal() = 0; + + // Centers the window and sizes it to the specified size. + virtual void CenterWindow(const gfx::Size& size) = 0; + + // Sets the NativeWindow title. + virtual void SetWindowTitle(const std::wstring& title) = 0; + + // Update native accessibility properties on the native window. + virtual void SetAccessibleName(const std::wstring& name) = 0; + virtual void SetAccessibleRole(AccessibilityTypes::Role role) = 0; + virtual void SetAccessibleState(AccessibilityTypes::State state) = 0; + + virtual NativeWidget* AsNativeWidget() = 0; + virtual const NativeWidget* AsNativeWidget() const = 0; }; } // namespace views diff --git a/views/window/native_window_delegate.h b/views/window/native_window_delegate.h index 8e963ce..711306c 100644 --- a/views/window/native_window_delegate.h +++ b/views/window/native_window_delegate.h @@ -19,8 +19,11 @@ class NativeWindowDelegate { public: virtual ~NativeWindowDelegate() {} - // Returns the window's preferred size. - virtual gfx::Size GetPreferredSize() const = 0; + // Returns true if the window is modal. + virtual bool IsModal() const = 0; + + // Called just after the NativeWindow has been created. + virtual void OnNativeWindowCreated(const gfx::Rect& bounds) = 0; // Called just before the native window is destroyed. This is the delegate's // last chance to do anything with the native window handle. diff --git a/views/window/window.cc b/views/window/window.cc index 5fbb222..24034cf 100644 --- a/views/window/window.cc +++ b/views/window/window.cc @@ -11,6 +11,8 @@ #include "ui/gfx/rect.h" #include "ui/gfx/size.h" #include "views/widget/widget.h" +#include "views/widget/native_widget.h" +#include "views/window/native_window.h" #include "views/window/window_delegate.h" namespace views { @@ -22,7 +24,9 @@ Window::Window(WindowDelegate* window_delegate) : native_window_(NULL), window_delegate_(window_delegate), ALLOW_THIS_IN_INITIALIZER_LIST( - non_client_view_(new NonClientView(this))) { + non_client_view_(new NonClientView(this))), + saved_maximized_state_(false), + minimum_size_(100, 100) { DCHECK(window_delegate_); DCHECK(!window_delegate_->window_); window_delegate_->window_ = this; @@ -80,6 +84,12 @@ void Window::SetWindowBounds(const gfx::Rect& bounds, } void Window::Show() { + native_window_->Show(saved_maximized_state_ ? NativeWindow::SHOW_MAXIMIZED + : NativeWindow::SHOW_RESTORED); + // |saved_maximized_state_| only applies the first time the window is shown. + // If we don't reset the value the window will be shown maximized every time + // it is subsequently shown after being hidden. + saved_maximized_state_ = false; } void Window::HideWindow() { @@ -144,6 +154,19 @@ void Window::EnableClose(bool enable) { } void Window::UpdateWindowTitle() { + // If the non-client view is rendering its own title, it'll need to relayout + // now. + non_client_view_->Layout(); + + // Update the native frame's text. We do this regardless of whether or not + // the native frame is being used, since this also updates the taskbar, etc. + std::wstring window_title; + if (native_window_->AsNativeWidget()->IsScreenReaderActive()) + window_title = window_delegate_->GetAccessibleWindowTitle(); + else + window_title = window_delegate_->GetWindowTitle(); + base::i18n::AdjustStringForLocaleDirection(&window_title); + native_window_->SetWindowTitle(window_title); } void Window::UpdateWindowIcon() { @@ -173,8 +196,26 @@ void Window::FrameTypeChanged() { //////////////////////////////////////////////////////////////////////////////// // Window, internal::NativeWindowDelegate implementation: -gfx::Size Window::GetPreferredSize() const { - return non_client_view_->GetPreferredSize(); +bool Window::IsModal() const { + return window_delegate_->IsModal(); +} + +void Window::OnNativeWindowCreated(const gfx::Rect& bounds) { + if (window_delegate_->IsModal()) + native_window_->BecomeModal(); + + // Create the ClientView, add it to the NonClientView and add the + // NonClientView to the RootView. This will cause everything to be parented. + non_client_view_->set_client_view(window_delegate_->CreateClientView(this)); + // TODO(beng): make simpler once Window subclasses Widget. + native_window_->AsNativeWidget()->GetWidget()->SetContentsView( + non_client_view_); + + UpdateWindowTitle(); + native_window_->SetAccessibleRole(window_delegate_->accessible_role()); + native_window_->SetAccessibleState(window_delegate_->accessible_state()); + + SetInitialBounds(bounds); } void Window::OnWindowDestroying() { @@ -187,4 +228,53 @@ void Window::OnWindowDestroyed() { window_delegate_ = NULL; } +//////////////////////////////////////////////////////////////////////////////// +// Window, private: + +void Window::SetInitialBounds(const gfx::Rect& bounds) { + // First we obtain the window's saved show-style and store it. We need to do + // this here, rather than in Show() because by the time Show() is called, + // the window's size will have been reset (below) and the saved maximized + // state will have been lost. Sadly there's no way to tell on Windows when + // a window is restored from maximized state, so we can't more accurately + // track maximized state independently of sizing information. + window_delegate_->GetSavedMaximizedState(&saved_maximized_state_); + + // Restore the window's placement from the controller. + gfx::Rect saved_bounds = bounds; + if (window_delegate_->GetSavedWindowBounds(&saved_bounds)) { + if (!window_delegate_->ShouldRestoreWindowSize()) { + saved_bounds.set_size(non_client_view_->GetPreferredSize()); + } else { + // Make sure the bounds are at least the minimum size. + if (saved_bounds.width() < minimum_size_.width()) { + saved_bounds.SetRect(saved_bounds.x(), saved_bounds.y(), + saved_bounds.right() + minimum_size_.width() - + saved_bounds.width(), + saved_bounds.bottom()); + } + + if (saved_bounds.height() < minimum_size_.height()) { + saved_bounds.SetRect(saved_bounds.x(), saved_bounds.y(), + saved_bounds.right(), + saved_bounds.bottom() + minimum_size_.height() - + saved_bounds.height()); + } + } + + // Widget's SetBounds method does not further modify the bounds that are + // passed to it. + native_window_->AsNativeWidget()->SetBounds(saved_bounds); + } else { + if (bounds.IsEmpty()) { + // No initial bounds supplied, so size the window to its content and + // center over its parent. + native_window_->CenterWindow(non_client_view_->GetPreferredSize()); + } else { + // Use the supplied initial bounds. + SetWindowBounds(bounds, NULL); + } + } +} + } // namespace views diff --git a/views/window/window.h b/views/window/window.h index ba7ed98..9775ed7 100644 --- a/views/window/window.h +++ b/views/window/window.h @@ -84,7 +84,7 @@ class Window : public internal::NativeWindowDelegate { gfx::NativeWindow other_window); // Makes the window visible. - virtual void Show(); + void Show(); // Hides the window. This does not delete the window, it just hides it. This // always hides the window, it is separate from the stack maintained by @@ -163,7 +163,7 @@ class Window : public internal::NativeWindowDelegate { virtual void EnableClose(bool enable); // Tell the window to update its title from the delegate. - virtual void UpdateWindowTitle(); + void UpdateWindowTitle(); // Tell the window to update its icon from the delegate. virtual void UpdateWindowIcon(); @@ -218,13 +218,17 @@ class Window : public internal::NativeWindowDelegate { } // Overridden from NativeWindowDelegate: - virtual gfx::Size GetPreferredSize() const; - virtual void OnWindowDestroying(); - virtual void OnWindowDestroyed(); + virtual bool IsModal() const OVERRIDE; + virtual void OnNativeWindowCreated(const gfx::Rect& bounds) OVERRIDE; + virtual void OnWindowDestroying() OVERRIDE; + virtual void OnWindowDestroyed() OVERRIDE; private: Window(); + // Sizes and positions the window just after it is created. + void SetInitialBounds(const gfx::Rect& bounds); + NativeWindow* native_window_; // Our window delegate (see InitWindow() method for documentation). @@ -236,6 +240,13 @@ class Window : public internal::NativeWindowDelegate { // desired implementation before calling |InitWindow()|. NonClientView* non_client_view_; + // The saved maximized state for this window. See note in SetInitialBounds + // that explains why we save this. + bool saved_maximized_state_; + + // The smallest size the window can be. + gfx::Size minimum_size_; + DISALLOW_COPY_AND_ASSIGN(Window); }; diff --git a/views/window/window_delegate.h b/views/window/window_delegate.h index fd7b1d1..e73a7fa 100644 --- a/views/window/window_delegate.h +++ b/views/window/window_delegate.h @@ -104,7 +104,8 @@ class WindowDelegate { // Default is true. virtual bool ShouldRestoreWindowSize() const; - // Called when the window closes. + // Called when the window closes. The delegate MUST NOT delete itself during + // this call, since it can be called afterwards. See DeleteDelegate(). virtual void WindowClosing() {} // Called when the window is destroyed. No events must be sent or received diff --git a/views/window/window_gtk.cc b/views/window/window_gtk.cc index 5eaea00..081b456 100644 --- a/views/window/window_gtk.cc +++ b/views/window/window_gtk.cc @@ -119,10 +119,6 @@ void WindowGtk::SetWindowBounds(const gfx::Rect& bounds, WidgetGtk::SetBounds(bounds); } -void WindowGtk::Show() { - gtk_widget_show(GetNativeView()); -} - void WindowGtk::HideWindow() { Hide(); } @@ -207,23 +203,6 @@ void WindowGtk::EnableClose(bool enable) { gtk_window_set_deletable(GetNativeWindow(), enable); } -void WindowGtk::UpdateWindowTitle() { - // ChromeOS doesn't use a window title, so don't update them. -#if !defined(OS_CHROMEOS) - - // If the non-client view is rendering its own title, it'll need to relayout - // now. - GetWindow()->non_client_view()->Layout(); - - // Update the native frame's text. We do this regardless of whether or not - // the native frame is being used, since this also updates the taskbar, etc. - std::wstring window_title = GetWindow()->window_delegate()->GetWindowTitle(); - base::i18n::AdjustStringForLocaleDirection(&window_title); - - gtk_window_set_title(GetNativeWindow(), WideToUTF8(window_title).c_str()); -#endif -} - void WindowGtk::UpdateWindowIcon() { // Doesn't matter for chrome os. } @@ -380,13 +359,68 @@ void WindowGtk::SetInitialFocus() { } //////////////////////////////////////////////////////////////////////////////// +// WindowGtk, NativeWindow implementation: + +void WindowGtk::Show(ShowState state) { + // No concept of maximization (yet) on ChromeOS. + gtk_widget_show(GetNativeView()); +} + +void WindowGtk::BecomeModal() { + gtk_window_set_modal(GetNativeWindow(), true); +} + +void WindowGtk::CenterWindow(const gfx::Size& size) { + gfx::Rect center_rect; + + GtkWindow* parent = gtk_window_get_transient_for(GetNativeWindow()); + if (parent) { + // We have a parent window, center over it. + gint parent_x = 0; + gint parent_y = 0; + gtk_window_get_position(parent, &parent_x, &parent_y); + gint parent_w = 0; + gint parent_h = 0; + gtk_window_get_size(parent, &parent_w, &parent_h); + center_rect = gfx::Rect(parent_x, parent_y, parent_w, parent_h); + } else { + // We have no parent window, center over the screen. + center_rect = Screen::GetMonitorWorkAreaNearestWindow(GetNativeView()); + } + gfx::Rect bounds(center_rect.x() + (center_rect.width() - size.width()) / 2, + center_rect.y() + (center_rect.height() - size.height()) / 2, + size.width(), size.height()); + SetWindowBounds(bounds, NULL); +} + +void WindowGtk::SetWindowTitle(const std::wstring& title) { + // We don't have a window title on ChromeOS (right now). +} + +void WindowGtk::SetAccessibleName(const std::wstring& name) { +} + +void WindowGtk::SetAccessibleRole(AccessibilityTypes::Role role) { +} + +void WindowGtk::SetAccessibleState(AccessibilityTypes::State state) { +} + +NativeWidget* WindowGtk::AsNativeWidget() { + return this; +} + +const NativeWidget* WindowGtk::AsNativeWidget() const { + return this; +} + +//////////////////////////////////////////////////////////////////////////////// // WindowGtk, protected: WindowGtk::WindowGtk(WindowDelegate* window_delegate) : WidgetGtk(TYPE_WINDOW), Window(window_delegate), ALLOW_THIS_IN_INITIALIZER_LIST(delegate_(this)), - is_modal_(false), window_state_(GDK_WINDOW_STATE_WITHDRAWN), window_closed_(false) { set_native_window(this); @@ -397,35 +431,12 @@ void WindowGtk::InitWindow(GtkWindow* parent, const gfx::Rect& bounds) { if (parent) make_transient_to_parent(); WidgetGtk::Init(GTK_WIDGET(parent), bounds); - - // We call this after initializing our members since our implementations of - // assorted WidgetWin functions may be called during initialization. - is_modal_ = GetWindow()->window_delegate()->IsModal(); - if (is_modal_) - gtk_window_set_modal(GetNativeWindow(), true); + delegate_->OnNativeWindowCreated(bounds); g_signal_connect(G_OBJECT(GetNativeWindow()), "configure-event", G_CALLBACK(CallConfigureEvent), this); g_signal_connect(G_OBJECT(GetNativeWindow()), "window-state-event", G_CALLBACK(CallWindowStateEvent), this); - - // Create the ClientView, add it to the NonClientView and add the - // NonClientView to the RootView. This will cause everything to be parented. - GetWindow()->non_client_view()->set_client_view( - GetWindow()->window_delegate()->CreateClientView(this)); - WidgetGtk::SetContentsView(GetWindow()->non_client_view()); - - UpdateWindowTitle(); - SetInitialBounds(parent, bounds); - - // if (!IsAppWindow()) { - // notification_registrar_.Add( - // this, - // NotificationType::ALL_APPWINDOWS_CLOSED, - // NotificationService::AllSources()); - // } - - // ResetWindowRegion(false); } //////////////////////////////////////////////////////////////////////////////// @@ -454,45 +465,6 @@ void WindowGtk::SaveWindowPosition() { GetWindow()->window_delegate()->SaveWindowPlacement(GetBounds(), maximized); } -void WindowGtk::SetInitialBounds(GtkWindow* parent, - const gfx::Rect& create_bounds) { - gfx::Rect saved_bounds(create_bounds.ToGdkRectangle()); - if (GetWindow()->window_delegate()->GetSavedWindowBounds(&saved_bounds)) { - if (!GetWindow()->window_delegate()->ShouldRestoreWindowSize()) - saved_bounds.set_size(delegate_->GetPreferredSize()); - WidgetGtk::SetBounds(saved_bounds); - } else { - if (create_bounds.IsEmpty()) { - SizeWindowToDefault(parent); - } else { - SetWindowBounds(create_bounds, NULL); - } - } -} - -void WindowGtk::SizeWindowToDefault(GtkWindow* parent) { - gfx::Rect center_rect; - - if (parent) { - // We have a parent window, center over it. - gint parent_x = 0; - gint parent_y = 0; - gtk_window_get_position(parent, &parent_x, &parent_y); - gint parent_w = 0; - gint parent_h = 0; - gtk_window_get_size(parent, &parent_w, &parent_h); - center_rect = gfx::Rect(parent_x, parent_y, parent_w, parent_h); - } else { - // We have no parent window, center over the screen. - center_rect = Screen::GetMonitorWorkAreaNearestWindow(GetNativeView()); - } - gfx::Size size = delegate_->GetPreferredSize(); - gfx::Rect bounds(center_rect.x() + (center_rect.width() - size.width()) / 2, - center_rect.y() + (center_rect.height() - size.height()) / 2, - size.width(), size.height()); - SetWindowBounds(bounds, NULL); -} - void WindowGtk::OnDestroy(GtkWidget* widget) { delegate_->OnWindowDestroying(); WidgetGtk::OnDestroy(widget); diff --git a/views/window/window_gtk.h b/views/window/window_gtk.h index ef1cde8..57ceeaa 100644 --- a/views/window/window_gtk.h +++ b/views/window/window_gtk.h @@ -34,7 +34,6 @@ class WindowGtk : public WidgetGtk, public NativeWindow, public Window { virtual gfx::Rect GetNormalBounds() const; virtual void SetWindowBounds(const gfx::Rect& bounds, gfx::NativeWindow other_window); - virtual void Show(); virtual void HideWindow(); virtual void SetNativeWindowProperty(const char* name, void* value); virtual void* GetNativeWindowProperty(const char* name); @@ -52,7 +51,6 @@ class WindowGtk : public WidgetGtk, public NativeWindow, public Window { virtual bool IsFullscreen() const; virtual void SetUseDragFrame(bool use_drag_frame); virtual void EnableClose(bool enable); - virtual void UpdateWindowTitle(); virtual void UpdateWindowIcon(); virtual void SetIsAlwaysOnTop(bool always_on_top); virtual NonClientFrameView* CreateFrameViewForWindow(); @@ -76,6 +74,17 @@ class WindowGtk : public WidgetGtk, public NativeWindow, public Window { virtual void SetInitialFocus(); protected: + // Overridden from NativeWindow: + virtual void Show(ShowState state) OVERRIDE; + virtual void BecomeModal() OVERRIDE; + virtual void CenterWindow(const gfx::Size& size) OVERRIDE; + virtual void SetWindowTitle(const std::wstring& title) OVERRIDE; + virtual void SetAccessibleName(const std::wstring& name) OVERRIDE; + virtual void SetAccessibleRole(AccessibilityTypes::Role role) OVERRIDE; + virtual void SetAccessibleState(AccessibilityTypes::State state) OVERRIDE; + virtual NativeWidget* AsNativeWidget() OVERRIDE; + virtual const NativeWidget* AsNativeWidget() const OVERRIDE; + // For the constructor. friend class Window; @@ -98,17 +107,9 @@ class WindowGtk : public WidgetGtk, public NativeWindow, public Window { // Asks the delegate if any to save the window's location and size. void SaveWindowPosition(); - void SetInitialBounds(GtkWindow* parent, const gfx::Rect& bounds); - void SizeWindowToDefault(GtkWindow* parent); - // A delegate implementation that handles events received here. internal::NativeWindowDelegate* delegate_; - // Whether or not the window is modal. This comes from the delegate and is - // cached at Init time to avoid calling back to the delegate from the - // destructor. - bool is_modal_; - // Our window delegate. WindowDelegate* window_delegate_; diff --git a/views/window/window_win.cc b/views/window/window_win.cc index 59d062a..635e563 100644 --- a/views/window/window_win.cc +++ b/views/window/window_win.cc @@ -115,6 +115,10 @@ bool EdgeHasTopmostAutoHideTaskbar(UINT edge, HMONITOR monitor) { (GetWindowLong(taskbar, GWL_EXSTYLE) & WS_EX_TOPMOST); } +HWND GetOwner(HWND window) { + return ::GetWindow(window, GW_OWNER); +} + } // namespace namespace views { @@ -303,13 +307,6 @@ static BOOL CALLBACK SendDwmCompositionChanged(HWND window, LPARAM param) { //////////////////////////////////////////////////////////////////////////////// // WindowWin, Window implementation: -void WindowWin::Show() { - int show_state = GetShowState(); - if (saved_maximized_state_) - show_state = SW_SHOWMAXIMIZED; - Show(show_state); -} - void WindowWin::Activate() { if (IsMinimized()) ::ShowWindow(GetNativeView(), SW_RESTORE); @@ -341,9 +338,10 @@ void WindowWin::Close() { // closes us, we want our owner to gain activation. But only if the owner // is visible. If we don't manually force that here, the other app will // regain activation instead. - if (owning_hwnd_ && GetNativeView() == GetForegroundWindow() && - IsWindowVisible(owning_hwnd_)) { - SetForegroundWindow(owning_hwnd_); + HWND owner = GetOwner(GetNativeView()); + if (owner && GetNativeView() == GetForegroundWindow() && + IsWindowVisible(owner)) { + SetForegroundWindow(owner); } window_closed_ = true; } @@ -478,25 +476,6 @@ void WindowWin::DisableInactiveRendering() { disable_inactive_rendering_); } -void WindowWin::UpdateWindowTitle() { - // If the non-client view is rendering its own title, it'll need to relayout - // now. - GetWindow()->non_client_view()->Layout(); - - // Update the native frame's text. We do this regardless of whether or not - // the native frame is being used, since this also updates the taskbar, etc. - std::wstring window_title; - if (IsAccessibleWidget()) - window_title = GetWindow()->window_delegate()->GetAccessibleWindowTitle(); - else - window_title = GetWindow()->window_delegate()->GetWindowTitle(); - base::i18n::AdjustStringForLocaleDirection(&window_title); - SetWindowText(GetNativeView(), window_title.c_str()); - - // Also update the accessibility name. - UpdateAccessibleName(window_title); -} - void WindowWin::UpdateWindowIcon() { // If the non-client view is rendering its own icon, we need to tell it to // repaint. @@ -606,9 +585,6 @@ WindowWin::WindowWin(WindowDelegate* window_delegate) Window(window_delegate), ALLOW_THIS_IN_INITIALIZER_LIST(delegate_(this)), focus_on_creation_(true), - owning_hwnd_(NULL), - minimum_size_(100, 100), - is_modal_(false), restored_enabled_(false), fullscreen_(false), window_closed_(false), @@ -616,7 +592,6 @@ WindowWin::WindowWin(WindowDelegate* window_delegate) is_active_(false), lock_updates_(false), saved_window_style_(0), - saved_maximized_state_(0), ignore_window_pos_changes_(false), ignore_pos_changes_factory_(this), force_hidden_count_(0), @@ -632,44 +607,18 @@ WindowWin::WindowWin(WindowDelegate* window_delegate) } void WindowWin::Init(gfx::NativeView parent, const gfx::Rect& bounds) { - // We need to save the parent window, since later calls to GetParent() will - // return NULL. - owning_hwnd_ = parent; - // We call this after initializing our members since our implementations of - // assorted WidgetWin functions may be called during initialization. - is_modal_ = GetWindow()->window_delegate()->IsModal(); - if (is_modal_) - BecomeModal(); - if (window_style() == 0) set_window_style(CalculateWindowStyle()); if (window_ex_style() == 0) set_window_ex_style(CalculateWindowExStyle()); - WidgetWin::Init(parent, bounds); - ui::SetWindowUserData(GetNativeView(), this); - - // Create the ClientView, add it to the NonClientView and add the - // NonClientView to the RootView. This will cause everything to be parented. - GetWindow()->non_client_view()->set_client_view( - GetWindow()->window_delegate()->CreateClientView(this)); - WidgetWin::SetContentsView(GetWindow()->non_client_view()); - - UpdateWindowTitle(); - UpdateAccessibleRole(); - UpdateAccessibleState(); - - SetInitialBounds(bounds); - GetMonitorAndRects(bounds.ToRECT(), &last_monitor_, &last_monitor_rect_, &last_work_area_); - ResetWindowRegion(false); -} -void WindowWin::SizeWindowToDefault() { - ui::CenterAndSizeWindow(owning_window(), GetNativeView(), - delegate_->GetPreferredSize(), - false); + WidgetWin::Init(parent, bounds); + + ui::SetWindowUserData(GetNativeView(), this); + delegate_->OnNativeWindowCreated(bounds); } gfx::Insets WindowWin::GetClientAreaInsets() const { @@ -1216,20 +1165,88 @@ void WindowWin::OnWindowPosChanging(WINDOWPOS* window_pos) { } //////////////////////////////////////////////////////////////////////////////// -// WindowWin, private: +// WindowWin, NativeWindow implementation: + +void WindowWin::Show(ShowState state) { + Show(state == SHOW_MAXIMIZED ? SW_SHOWMAXIMIZED : GetShowState()); +} void WindowWin::BecomeModal() { // We implement modality by crawling up the hierarchy of windows starting // at the owner, disabling all of them so that they don't receive input // messages. - DCHECK(owning_hwnd_) << "Can't create a modal dialog without an owner"; - HWND start = owning_hwnd_; - while (start != NULL) { + HWND start = GetOwner(GetNativeView()); + while (start) { ::EnableWindow(start, FALSE); start = ::GetParent(start); } } +void WindowWin::CenterWindow(const gfx::Size& size) { + HWND parent = GetParent(); + if (!IsWindow()) + parent = GetOwner(GetNativeView()); + ui::CenterAndSizeWindow(parent, GetNativeView(), size, false); +} + +void WindowWin::SetWindowTitle(const std::wstring& title) { + SetWindowText(GetNativeView(), title.c_str()); + SetAccessibleName(title); +} + +void WindowWin::SetAccessibleName(const std::wstring& name) { + base::win::ScopedComPtr pAccPropServices; + HRESULT hr = CoCreateInstance(CLSID_AccPropServices, NULL, CLSCTX_SERVER, + IID_IAccPropServices, reinterpret_cast(&pAccPropServices)); + if (SUCCEEDED(hr)) { + VARIANT var; + var.vt = VT_BSTR; + var.bstrVal = SysAllocString(name.c_str()); + hr = pAccPropServices->SetHwndProp(GetNativeView(), OBJID_CLIENT, + CHILDID_SELF, PROPID_ACC_NAME, var); + } +} + +void WindowWin::SetAccessibleRole(AccessibilityTypes::Role role) { + base::win::ScopedComPtr pAccPropServices; + HRESULT hr = CoCreateInstance(CLSID_AccPropServices, NULL, CLSCTX_SERVER, + IID_IAccPropServices, reinterpret_cast(&pAccPropServices)); + if (SUCCEEDED(hr)) { + VARIANT var; + if (role) { + var.vt = VT_I4; + var.lVal = ViewAccessibility::MSAARole(role); + hr = pAccPropServices->SetHwndProp(GetNativeView(), OBJID_CLIENT, + CHILDID_SELF, PROPID_ACC_ROLE, var); + } + } +} + +void WindowWin::SetAccessibleState(AccessibilityTypes::State state) { + base::win::ScopedComPtr pAccPropServices; + HRESULT hr = CoCreateInstance(CLSID_AccPropServices, NULL, CLSCTX_SERVER, + IID_IAccPropServices, reinterpret_cast(&pAccPropServices)); + if (SUCCEEDED(hr)) { + VARIANT var; + if (state) { + var.lVal = ViewAccessibility::MSAAState(state); + hr = pAccPropServices->SetHwndProp(GetNativeView(), OBJID_CLIENT, + CHILDID_SELF, PROPID_ACC_STATE, var); + } + } +} + +NativeWidget* WindowWin::AsNativeWidget() { + return this; +} + +const NativeWidget* WindowWin::AsNativeWidget() const { + return this; +} + +//////////////////////////////////////////////////////////////////////////////// +// WindowWin, private: + void WindowWin::SetInitialFocus() { if (!focus_on_creation_) return; @@ -1244,63 +1261,13 @@ void WindowWin::SetInitialFocus() { } } -void WindowWin::SetInitialBounds(const gfx::Rect& create_bounds) { - // First we obtain the window's saved show-style and store it. We need to do - // this here, rather than in Show() because by the time Show() is called, - // the window's size will have been reset (below) and the saved maximized - // state will have been lost. Sadly there's no way to tell on Windows when - // a window is restored from maximized state, so we can't more accurately - // track maximized state independently of sizing information. - GetWindow()->window_delegate()->GetSavedMaximizedState( - &saved_maximized_state_); - - // Restore the window's placement from the controller. - gfx::Rect saved_bounds(create_bounds.ToRECT()); - if (GetWindow()->window_delegate()->GetSavedWindowBounds(&saved_bounds)) { - if (!GetWindow()->window_delegate()->ShouldRestoreWindowSize()) { - saved_bounds.set_size(delegate_->GetPreferredSize()); - } else { - // Make sure the bounds are at least the minimum size. - if (saved_bounds.width() < minimum_size_.width()) { - saved_bounds.SetRect(saved_bounds.x(), saved_bounds.y(), - saved_bounds.right() + minimum_size_.width() - - saved_bounds.width(), - saved_bounds.bottom()); - } - - if (saved_bounds.height() < minimum_size_.height()) { - saved_bounds.SetRect(saved_bounds.x(), saved_bounds.y(), - saved_bounds.right(), - saved_bounds.bottom() + minimum_size_.height() - - saved_bounds.height()); - } - } - - // "Show state" (maximized, minimized, etc) is handled by Show(). - // Don't use SetBounds here. SetBounds constrains to the size of the - // monitor, but we don't want that when creating a new window as the result - // of dragging out a tab to create a new window. - SetWindowPos(NULL, saved_bounds.x(), saved_bounds.y(), - saved_bounds.width(), saved_bounds.height(), 0); - } else { - if (create_bounds.IsEmpty()) { - // No initial bounds supplied, so size the window to its content and - // center over its parent. - SizeWindowToDefault(); - } else { - // Use the supplied initial bounds. - SetWindowBounds(create_bounds, NULL); - } - } -} - void WindowWin::RestoreEnabledIfNecessary() { - if (is_modal_ && !restored_enabled_) { + if (delegate_->IsModal() && !restored_enabled_) { restored_enabled_ = true; // If we were run modally, we need to undo the disabled-ness we inflicted on // the owner's parent hierarchy. - HWND start = owning_hwnd_; - while (start != NULL) { + HWND start = GetOwner(GetNativeView()); + while (start) { ::EnableWindow(start, TRUE); start = ::GetParent(start); } @@ -1403,52 +1370,6 @@ void WindowWin::ResetWindowRegion(bool force) { DeleteObject(current_rgn); } -void WindowWin::UpdateAccessibleName(std::wstring& accessible_name) { - base::win::ScopedComPtr pAccPropServices; - HRESULT hr = CoCreateInstance(CLSID_AccPropServices, NULL, CLSCTX_SERVER, - IID_IAccPropServices, reinterpret_cast(&pAccPropServices)); - if (SUCCEEDED(hr)) { - VARIANT var; - var.vt = VT_BSTR; - var.bstrVal = SysAllocString(accessible_name.c_str()); - hr = pAccPropServices->SetHwndProp(GetNativeView(), OBJID_CLIENT, - CHILDID_SELF, PROPID_ACC_NAME, var); - } -} - -void WindowWin::UpdateAccessibleRole() { - base::win::ScopedComPtr pAccPropServices; - HRESULT hr = CoCreateInstance(CLSID_AccPropServices, NULL, CLSCTX_SERVER, - IID_IAccPropServices, reinterpret_cast(&pAccPropServices)); - if (SUCCEEDED(hr)) { - VARIANT var; - AccessibilityTypes::Role role = - GetWindow()->window_delegate()->accessible_role(); - if (role) { - var.vt = VT_I4; - var.lVal = ViewAccessibility::MSAARole(role); - hr = pAccPropServices->SetHwndProp(GetNativeView(), OBJID_CLIENT, - CHILDID_SELF, PROPID_ACC_ROLE, var); - } - } -} - -void WindowWin::UpdateAccessibleState() { - base::win::ScopedComPtr pAccPropServices; - HRESULT hr = CoCreateInstance(CLSID_AccPropServices, NULL, CLSCTX_SERVER, - IID_IAccPropServices, reinterpret_cast(&pAccPropServices)); - if (SUCCEEDED(hr)) { - VARIANT var; - AccessibilityTypes::State state = - GetWindow()->window_delegate()->accessible_state(); - if (state) { - var.lVal = ViewAccessibility::MSAAState(state); - hr = pAccPropServices->SetHwndProp(GetNativeView(), OBJID_CLIENT, - CHILDID_SELF, PROPID_ACC_STATE, var); - } - } -} - LRESULT WindowWin::CallDefaultNCActivateHandler(BOOL active) { // The DefWindowProc handling for WM_NCACTIVATE renders the classic-look // window title bar directly, so we need to use a redraw lock here to prevent diff --git a/views/window/window_win.h b/views/window/window_win.h index ff85b4c..5f291dd 100644 --- a/views/window/window_win.h +++ b/views/window/window_win.h @@ -50,7 +50,6 @@ class WindowWin : public WidgetWin, void Show(int show_state); // Accessors and setters for various properties. - HWND owning_window() const { return owning_hwnd_; } void set_focus_on_creation(bool focus_on_creation) { focus_on_creation_ = focus_on_creation; } @@ -60,7 +59,6 @@ class WindowWin : public WidgetWin, virtual gfx::Rect GetNormalBounds() const OVERRIDE; virtual void SetWindowBounds(const gfx::Rect& bounds, gfx::NativeWindow other_window) OVERRIDE; - virtual void Show() OVERRIDE; virtual void HideWindow() OVERRIDE; virtual void SetNativeWindowProperty(const char* name, void* value) OVERRIDE; virtual void* GetNativeWindowProperty(const char* name) OVERRIDE; @@ -81,7 +79,6 @@ class WindowWin : public WidgetWin, virtual void SetUseDragFrame(bool use_drag_frame) OVERRIDE; virtual void EnableClose(bool enable) OVERRIDE; virtual void DisableInactiveRendering() OVERRIDE; - virtual void UpdateWindowTitle() OVERRIDE; virtual void UpdateWindowIcon() OVERRIDE; virtual void SetIsAlwaysOnTop(bool always_on_top) OVERRIDE; virtual NonClientFrameView* CreateFrameViewForWindow() OVERRIDE; @@ -105,9 +102,6 @@ class WindowWin : public WidgetWin, // centered on screen. virtual void Init(gfx::NativeView parent, const gfx::Rect& bounds) OVERRIDE; - // Sizes the window to the default size specified by its ClientView. - virtual void SizeWindowToDefault(); - // Returns the insets of the client area relative to the non-client area of // the window. Override this function instead of OnNCCalcSize, which is // crazily complicated. @@ -120,6 +114,11 @@ class WindowWin : public WidgetWin, // show state from the shortcut starutp info). virtual int GetShowState() const; + // Accessor for disable_inactive_rendering_. + bool disable_inactive_rendering() const { + return disable_inactive_rendering_; + } + // Overridden from WidgetWin: virtual void OnActivate(UINT action, BOOL minimized, HWND window) OVERRIDE; virtual void OnActivateApp(BOOL active, DWORD thread_id) OVERRIDE; @@ -156,10 +155,16 @@ class WindowWin : public WidgetWin, virtual Window* GetWindow() OVERRIDE { return this; } virtual const Window* GetWindow() const OVERRIDE { return this; } - // Accessor for disable_inactive_rendering_. - bool disable_inactive_rendering() const { - return disable_inactive_rendering_; - } + // Overridden from NativeWindow: + virtual void Show(ShowState state); + virtual void BecomeModal() OVERRIDE; + virtual void CenterWindow(const gfx::Size& size) OVERRIDE; + virtual void SetWindowTitle(const std::wstring& title) OVERRIDE; + virtual void SetAccessibleName(const std::wstring& name) OVERRIDE; + virtual void SetAccessibleRole(AccessibilityTypes::Role role) OVERRIDE; + virtual void SetAccessibleState(AccessibilityTypes::State state) OVERRIDE; + virtual NativeWidget* AsNativeWidget() OVERRIDE; + virtual const NativeWidget* AsNativeWidget() const OVERRIDE; private: // Information saved before going into fullscreen mode, used to restore the @@ -171,18 +176,11 @@ class WindowWin : public WidgetWin, RECT window_rect; }; - // Sets the window as modal (by disabling all the other windows). - void BecomeModal(); - // Sets-up the focus manager with the view that should have focus when the // window is shown the first time. If NULL is returned, the focus goes to the // button if there is one, otherwise the to the Cancel button. void SetInitialFocus(); - // Place and size the window when it is created. |create_bounds| are the - // bounds used when the window was created. - void SetInitialBounds(const gfx::Rect& create_bounds); - // If necessary, enables all ancestors. void RestoreEnabledIfNecessary(); @@ -239,18 +237,6 @@ class WindowWin : public WidgetWin, // Init(). Defaults to true. bool focus_on_creation_; - // We need to save the parent window that spawned us, since GetParent() - // returns NULL for dialogs. - HWND owning_hwnd_; - - // The smallest size the window can be. - gfx::Size minimum_size_; - - // Whether or not the window is modal. This comes from the delegate and is - // cached at Init time to avoid calling back to the delegate from the - // destructor. - bool is_modal_; - // Whether all ancestors have been enabled. This is only used if is_modal_ is // true. bool restored_enabled_; @@ -277,10 +263,6 @@ class WindowWin : public WidgetWin, // The window styles of the window before updates were locked. DWORD saved_window_style_; - // The saved maximized state for this window. See note in SetInitialBounds - // that explains why we save this. - bool saved_maximized_state_; - // When true, this flag makes us discard incoming SetWindowPos() requests that // only change our position/size. (We still allow changes to Z-order, // activation, etc.) -- cgit v1.1