diff options
author | ben@chromium.org <ben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-03-09 23:01:19 +0000 |
---|---|---|
committer | ben@chromium.org <ben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-03-09 23:01:19 +0000 |
commit | 980bc2230826afde1159a7d8e02baa0095edb151 (patch) | |
tree | 4429e9e656db7114f7580833682424a1db0d9c4e /views | |
parent | aad9e115facc9f168550287267c1dbe5fdb70e17 (diff) | |
download | chromium_src-980bc2230826afde1159a7d8e02baa0095edb151.zip chromium_src-980bc2230826afde1159a7d8e02baa0095edb151.tar.gz chromium_src-980bc2230826afde1159a7d8e02baa0095edb151.tar.bz2 |
Consolidate more into Window.
- various window attributes
BUG=72040
TEST=none
Review URL: http://codereview.chromium.org/6661003
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@77538 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'views')
-rw-r--r-- | views/window/native_window.h | 15 | ||||
-rw-r--r-- | views/window/native_window_delegate.h | 27 | ||||
-rw-r--r-- | views/window/window.cc | 71 | ||||
-rw-r--r-- | views/window/window.h | 29 | ||||
-rw-r--r-- | views/window/window_gtk.cc | 43 | ||||
-rw-r--r-- | views/window/window_gtk.h | 8 | ||||
-rw-r--r-- | views/window/window_win.cc | 250 | ||||
-rw-r--r-- | views/window/window_win.h | 21 |
8 files changed, 252 insertions, 212 deletions
diff --git a/views/window/native_window.h b/views/window/native_window.h index f845dc0..8e5ac66 100644 --- a/views/window/native_window.h +++ b/views/window/native_window.h @@ -24,6 +24,13 @@ class NativeWindow { virtual ~NativeWindow() {} + protected: + friend class Window; + + // Returns the bounds of the window in screen coordinates for its non- + // maximized state, regardless of whether or not it is currently maximized. + virtual gfx::Rect GetRestoredBounds() const = 0; + // Shows the window. virtual void ShowNativeWindow(ShowState state) = 0; @@ -33,6 +40,14 @@ class NativeWindow { // Centers the window and sizes it to the specified size. virtual void CenterWindow(const gfx::Size& size) = 0; + // Retrieves the window's current restored bounds and maximized state, for + // persisting. + virtual void GetWindowBoundsAndMaximizedState(gfx::Rect* bounds, + bool* maximized) const = 0; + + // Enables or disables the close button for the window. + virtual void EnableClose(bool enable) = 0; + // Sets the NativeWindow title. virtual void SetWindowTitle(const std::wstring& title) = 0; diff --git a/views/window/native_window_delegate.h b/views/window/native_window_delegate.h index 40ccfaf..8e3eb02 100644 --- a/views/window/native_window_delegate.h +++ b/views/window/native_window_delegate.h @@ -25,15 +25,38 @@ class NativeWindowDelegate { // Returns true if the window is modal. virtual bool IsModal() const = 0; + // Returns true if the window is a dialog box. + virtual bool IsDialogBox() const = 0; + + // Returns true if the window is using a system native frame. Returns false if + // it is rendering its own title bar, borders and controls. + virtual bool IsUsingNativeFrame() const = 0; + + // Returns the smallest size the window can be resized to by the user. + virtual gfx::Size GetMinimumSize() const = 0; + + // Returns the non-client component (see views/window/hit_test.h) containing + // |point|, in client coordinates. + virtual int GetNonClientComponent(const gfx::Point& point) const = 0; + + // Runs the specified native command. Returns true if the command is handled. + virtual bool ExecuteCommand(int command_id) = 0; + // Called just after the NativeWindow has been created. virtual void OnNativeWindowCreated(const gfx::Rect& bounds) = 0; + // Called when the activation state of a window has changed. + virtual void OnNativeWindowActivationChanged(bool active) = 0; + // Called just before the native window is destroyed. This is the delegate's // last chance to do anything with the native window handle. - virtual void OnWindowDestroying() = 0; + virtual void OnNativeWindowDestroying() = 0; // Called just after the native window is destroyed. - virtual void OnWindowDestroyed() = 0; + virtual void OnNativeWindowDestroyed() = 0; + + // Called when the native window's position or size has changed. + virtual void OnNativeWindowBoundsChanged() = 0; }; } // namespace internal diff --git a/views/window/window.cc b/views/window/window.cc index 66826c6..ee4883f 100644 --- a/views/window/window.cc +++ b/views/window/window.cc @@ -28,7 +28,8 @@ Window::Window(WindowDelegate* window_delegate) non_client_view_(new NonClientView(this))), saved_maximized_state_(false), minimum_size_(100, 100), - disable_inactive_rendering_(false) { + disable_inactive_rendering_(false), + window_closed_(false) { DCHECK(window_delegate_); DCHECK(!window_delegate_->window_); window_delegate_->window_ = this; @@ -74,11 +75,12 @@ void Window::CloseSecondaryWidget(Widget* widget) { } gfx::Rect Window::GetBounds() const { - return gfx::Rect(); + // TODO(beng): Clean this up once Window subclasses Widget. + return native_window_->AsNativeWidget()->GetWidget()->GetWindowScreenBounds(); } gfx::Rect Window::GetNormalBounds() const { - return gfx::Rect(); + return native_window_->GetRestoredBounds(); } void Window::SetWindowBounds(const gfx::Rect& bounds, @@ -117,6 +119,20 @@ void Window::Deactivate() { } void Window::Close() { + if (window_closed_) { + // It appears we can hit this code path if you close a modal dialog then + // close the last browser before the destructor is hit, which triggers + // invoking Close again. + return; + } + + if (non_client_view_->CanClose()) { + SaveWindowPosition(); + // TODO(beng): This can be simplified to Widget::Close() once Window + // subclasses Widget. + native_window_->AsNativeWidget()->GetWidget()->Close(); + window_closed_ = true; + } } void Window::Maximize() { @@ -159,6 +175,8 @@ bool Window::IsAppWindow() const { } void Window::EnableClose(bool enable) { + non_client_view_->EnableClose(enable); + native_window_->EnableClose(enable); } void Window::UpdateWindowTitle() { @@ -220,6 +238,26 @@ bool Window::IsModal() const { return window_delegate_->IsModal(); } +bool Window::IsDialogBox() const { + return !!window_delegate_->AsDialogDelegate(); +} + +bool Window::IsUsingNativeFrame() const { + return non_client_view_->UseNativeFrame(); +} + +gfx::Size Window::GetMinimumSize() const { + return non_client_view_->GetMinimumSize(); +} + +int Window::GetNonClientComponent(const gfx::Point& point) const { + return non_client_view_->NonClientHitTest(point); +} + +bool Window::ExecuteCommand(int command_id) { + return window_delegate_->ExecuteWindowsCommand(command_id); +} + void Window::OnNativeWindowCreated(const gfx::Rect& bounds) { if (window_delegate_->IsModal()) native_window_->BecomeModal(); @@ -238,16 +276,25 @@ void Window::OnNativeWindowCreated(const gfx::Rect& bounds) { SetInitialBounds(bounds); } -void Window::OnWindowDestroying() { +void Window::OnNativeWindowActivationChanged(bool active) { + if (!active) + SaveWindowPosition(); +} + +void Window::OnNativeWindowDestroying() { non_client_view_->WindowClosing(); window_delegate_->WindowClosing(); } -void Window::OnWindowDestroyed() { +void Window::OnNativeWindowDestroyed() { window_delegate_->DeleteDelegate(); window_delegate_ = NULL; } +void Window::OnNativeWindowBoundsChanged() { + SaveWindowPosition(); +} + //////////////////////////////////////////////////////////////////////////////// // Window, private: @@ -299,4 +346,18 @@ void Window::SetInitialBounds(const gfx::Rect& bounds) { } } +void Window::SaveWindowPosition() { + // The window delegate does the actual saving for us. It seems like (judging + // by go/crash) that in some circumstances we can end up here after + // WM_DESTROY, at which point the window delegate is likely gone. So just + // bail. + if (!window_delegate_) + return; + + bool maximized; + gfx::Rect bounds; + native_window_->GetWindowBoundsAndMaximizedState(&bounds, &maximized); + window_delegate_->SaveWindowPlacement(bounds, maximized); +} + } // namespace views diff --git a/views/window/window.h b/views/window/window.h index dddc21b..dcdef3b 100644 --- a/views/window/window.h +++ b/views/window/window.h @@ -71,7 +71,7 @@ class Window : public internal::NativeWindowDelegate { static void CloseSecondaryWidget(Widget* widget); // Retrieves the window's bounds, including its frame. - virtual gfx::Rect GetBounds() const; + gfx::Rect GetBounds() const; // Retrieves the restored bounds for the window. virtual gfx::Rect GetNormalBounds() const; @@ -123,11 +123,10 @@ class Window : public internal::NativeWindowDelegate { // window. virtual void Deactivate(); - // Closes the window, ultimately destroying it. This isn't immediate (it - // occurs after a return to the message loop. Implementors must also make sure - // that invoking Close multiple times doesn't cause bad things to happen, - // since it can happen. - virtual void Close(); + // Closes the window, ultimately destroying it. The window hides immediately, + // and is destroyed after a return to the message loop. Close() can be called + // multiple times. + void Close(); // Maximizes/minimizes/restores the window. virtual void Maximize(); @@ -220,9 +219,16 @@ class Window : public internal::NativeWindowDelegate { virtual bool IsInactiveRenderingDisabled() const OVERRIDE; virtual void EnableInactiveRendering() OVERRIDE; virtual bool IsModal() const OVERRIDE; + virtual bool IsDialogBox() const OVERRIDE; + virtual bool IsUsingNativeFrame() const OVERRIDE; + virtual gfx::Size GetMinimumSize() const OVERRIDE; + virtual int GetNonClientComponent(const gfx::Point& point) const OVERRIDE; + virtual bool ExecuteCommand(int command_id) OVERRIDE; virtual void OnNativeWindowCreated(const gfx::Rect& bounds) OVERRIDE; - virtual void OnWindowDestroying() OVERRIDE; - virtual void OnWindowDestroyed() OVERRIDE; + virtual void OnNativeWindowActivationChanged(bool active) OVERRIDE; + virtual void OnNativeWindowDestroying() OVERRIDE; + virtual void OnNativeWindowDestroyed() OVERRIDE; + virtual void OnNativeWindowBoundsChanged() OVERRIDE; private: Window(); @@ -230,6 +236,10 @@ class Window : public internal::NativeWindowDelegate { // Sizes and positions the window just after it is created. void SetInitialBounds(const gfx::Rect& bounds); + // Persists the window's restored position and maximized state using the + // window delegate. + void SaveWindowPosition(); + NativeWindow* native_window_; // Our window delegate (see InitWindow() method for documentation). @@ -252,6 +262,9 @@ class Window : public internal::NativeWindowDelegate { // or not it actually is. bool disable_inactive_rendering_; + // Set to true if the window is in the process of closing . + bool window_closed_; + DISALLOW_COPY_AND_ASSIGN(Window); }; diff --git a/views/window/window_gtk.cc b/views/window/window_gtk.cc index 46cce43..d708e2d 100644 --- a/views/window/window_gtk.cc +++ b/views/window/window_gtk.cc @@ -104,15 +104,6 @@ void Window::CloseAllSecondaryWindows() { g_list_free(windows); } -gfx::Rect WindowGtk::GetBounds() const { - return GetWindowScreenBounds(); -} - -gfx::Rect WindowGtk::GetNormalBounds() const { - // We currently don't support tiling, so this doesn't matter. - return GetBounds(); -} - void WindowGtk::SetWindowBounds(const gfx::Rect& bounds, gfx::NativeWindow other_window) { // TODO: need to deal with other_window. @@ -139,18 +130,6 @@ void WindowGtk::Deactivate() { gdk_window_lower(GTK_WIDGET(GetNativeView())->window); } -void WindowGtk::Close() { - if (window_closed_) { - // Don't do anything if we've already been closed. - return; - } - - if (GetWindow()->non_client_view()->CanClose()) { - WidgetGtk::Close(); - window_closed_ = true; - } -} - void WindowGtk::Maximize() { gtk_window_maximize(GetNativeWindow()); } @@ -199,10 +178,6 @@ void WindowGtk::SetUseDragFrame(bool use_drag_frame) { NOTIMPLEMENTED(); } -void WindowGtk::EnableClose(bool enable) { - gtk_window_set_deletable(GetNativeWindow(), enable); -} - void WindowGtk::SetIsAlwaysOnTop(bool always_on_top) { gtk_window_set_keep_above(GetNativeWindow(), always_on_top); } @@ -357,6 +332,11 @@ void WindowGtk::SetInitialFocus() { //////////////////////////////////////////////////////////////////////////////// // WindowGtk, NativeWindow implementation: +gfx::Rect WindowGtk::GetRestoredBounds() const { + // We currently don't support tiling, so this doesn't matter. + return GetWindowScreenBounds(); +} + void WindowGtk::ShowNativeWindow(ShowState state) { // No concept of maximization (yet) on ChromeOS. gtk_widget_show(GetNativeView()); @@ -389,6 +369,15 @@ void WindowGtk::CenterWindow(const gfx::Size& size) { SetWindowBounds(bounds, NULL); } +void WindowGtk::GetWindowBoundsAndMaximizedState(gfx::Rect* bounds, + bool* maximized) const { + // Do nothing for now. ChromeOS isn't yet saving window placement. +} + +void WindowGtk::EnableClose(bool enable) { + gtk_window_set_deletable(GetNativeWindow(), enable); +} + void WindowGtk::SetWindowTitle(const std::wstring& title) { // We don't have a window title on ChromeOS (right now). } @@ -467,9 +456,9 @@ void WindowGtk::SaveWindowPosition() { } void WindowGtk::OnDestroy(GtkWidget* widget) { - delegate_->OnWindowDestroying(); + delegate_->OnNativeWindowDestroying(); WidgetGtk::OnDestroy(widget); - delegate_->OnWindowDestroyed(); + delegate_->OnNativeWindowDestroyed(); } } // namespace views diff --git a/views/window/window_gtk.h b/views/window/window_gtk.h index 6f05cae..91399e8 100644 --- a/views/window/window_gtk.h +++ b/views/window/window_gtk.h @@ -30,8 +30,6 @@ class WindowGtk : public WidgetGtk, public NativeWindow, public Window { virtual ~WindowGtk(); // Overridden from Window: - virtual gfx::Rect GetBounds() const; - virtual gfx::Rect GetNormalBounds() const; virtual void SetWindowBounds(const gfx::Rect& bounds, gfx::NativeWindow other_window); virtual void HideWindow(); @@ -39,7 +37,6 @@ class WindowGtk : public WidgetGtk, public NativeWindow, public Window { virtual void* GetNativeWindowProperty(const char* name); virtual void Activate(); virtual void Deactivate(); - virtual void Close(); virtual void Maximize(); virtual void Minimize(); virtual void Restore(); @@ -50,7 +47,6 @@ class WindowGtk : public WidgetGtk, public NativeWindow, public Window { virtual void SetFullscreen(bool fullscreen); virtual bool IsFullscreen() const; virtual void SetUseDragFrame(bool use_drag_frame); - virtual void EnableClose(bool enable); virtual void SetIsAlwaysOnTop(bool always_on_top); virtual NonClientFrameView* CreateFrameViewForWindow(); virtual void UpdateFrameAfterFrameChange(); @@ -74,9 +70,13 @@ class WindowGtk : public WidgetGtk, public NativeWindow, public Window { protected: // Overridden from NativeWindow: + virtual gfx::Rect GetRestoredBounds() const OVERRIDE; virtual void ShowNativeWindow(ShowState state) OVERRIDE; virtual void BecomeModal() OVERRIDE; virtual void CenterWindow(const gfx::Size& size) OVERRIDE; + virtual void GetWindowBoundsAndMaximizedState(gfx::Rect* bounds, + bool* maximized) const OVERRIDE; + virtual void EnableClose(bool enable) OVERRIDE; virtual void SetWindowTitle(const std::wstring& title) OVERRIDE; virtual void SetWindowIcons(const SkBitmap& window_icon, const SkBitmap& app_icon) OVERRIDE; diff --git a/views/window/window_win.cc b/views/window/window_win.cc index f7c9c8b..96709ba 100644 --- a/views/window/window_win.cc +++ b/views/window/window_win.cc @@ -28,6 +28,7 @@ #include "views/window/non_client_view.h" #include "views/window/window_delegate.h" +namespace views { namespace { static const int kDragFrameWindowAlpha = 200; @@ -94,8 +95,8 @@ void SetChildBounds(HWND child_window, HWND parent_window, } gfx::Rect actual_bounds = bounds; - views::internal::EnsureRectIsVisibleInRect(gfx::Rect(parent_rect), - &actual_bounds, padding); + internal::EnsureRectIsVisibleInRect(gfx::Rect(parent_rect), &actual_bounds, + padding); SetWindowPos(child_window, insert_after_window, actual_bounds.x(), actual_bounds.y(), actual_bounds.width(), @@ -119,9 +120,26 @@ HWND GetOwner(HWND window) { return ::GetWindow(window, GW_OWNER); } -} // namespace +// Tells the window its frame (non-client area) has changed. +void SendFrameChanged(HWND window) { + SetWindowPos(window, NULL, 0, 0, 0, 0, + SWP_FRAMECHANGED | SWP_NOACTIVATE | SWP_NOCOPYBITS | + SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_NOREPOSITION | + SWP_NOSENDCHANGING | SWP_NOSIZE | SWP_NOZORDER); +} -namespace views { +// Enables or disables the menu item for the specified command and menu. +void EnableMenuItem(HMENU menu, UINT command, bool enabled) { + UINT flags = MF_BYCOMMAND | (enabled ? MF_ENABLED : MF_DISABLED | MF_GRAYED); + EnableMenuItem(menu, command, flags); +} + +// If the hung renderer warning doesn't fit on screen, the amount of padding to +// be left between the edge of the window and the edge of the nearest monitor, +// after the window is nudged back on screen. Pixels. +const int kMonitorEdgePadding = 10; + +} // namespace namespace internal { @@ -206,11 +224,6 @@ class WindowWin::ScopedRedrawLock { HCURSOR WindowWin::resize_cursors_[6]; -// If the hung renderer warning doesn't fit on screen, the amount of padding to -// be left between the edge of the window and the edge of the nearest monitor, -// after the window is nudged back on screen. Pixels. -static const int kMonitorEdgePadding = 10; - //////////////////////////////////////////////////////////////////////////////// // WindowWin, public: @@ -228,21 +241,6 @@ Window* Window::CreateChromeWindow(gfx::NativeWindow parent, return window; } -gfx::Rect WindowWin::GetBounds() const { - return GetWindowScreenBounds(); -} - -gfx::Rect WindowWin::GetNormalBounds() const { - // If we're in fullscreen mode, we've changed the normal bounds to the monitor - // rect, so return the saved bounds instead. - if (IsFullscreen()) - return gfx::Rect(saved_window_info_.window_rect); - - gfx::Rect bounds; - GetWindowBoundsAndMaximizedState(&bounds, NULL); - return bounds; -} - void WindowWin::SetWindowBounds(const gfx::Rect& bounds, gfx::NativeWindow other_window) { SetChildBounds(GetNativeView(), GetParent(), other_window, bounds, @@ -321,32 +319,6 @@ void WindowWin::Deactivate() { ::SetForegroundWindow(hwnd); } -void WindowWin::Close() { - if (window_closed_) { - // It appears we can hit this code path if you close a modal dialog then - // close the last browser before the destructor is hit, which triggers - // invoking Close again. I'm short circuiting this code path to avoid - // calling into the delegate twice, which is problematic. - return; - } - - if (GetWindow()->non_client_view()->CanClose()) { - SaveWindowPosition(); - RestoreEnabledIfNecessary(); - WidgetWin::Close(); - // If the user activates another app after opening us, then comes back and - // 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. - HWND owner = GetOwner(GetNativeView()); - if (owner && GetNativeView() == GetForegroundWindow() && - IsWindowVisible(owner)) { - SetForegroundWindow(owner); - } - window_closed_ = true; - } -} - void WindowWin::Maximize() { ExecuteSystemMenuCommand(SC_MAXIMIZE); } @@ -454,22 +426,6 @@ void WindowWin::SetUseDragFrame(bool use_drag_frame) { } } -void WindowWin::EnableClose(bool enable) { - // If the native frame is rendering its own close button, ask it to disable. - GetWindow()->non_client_view()->EnableClose(enable); - - // Disable the native frame's close button regardless of whether or not the - // native frame is in use, since this also affects the system menu. - EnableMenuItem(GetSystemMenu(GetNativeView(), false), - SC_CLOSE, enable ? MF_ENABLED : MF_GRAYED); - - // Let the window know the frame changed. - SetWindowPos(NULL, 0, 0, 0, 0, - SWP_FRAMECHANGED | SWP_NOACTIVATE | SWP_NOCOPYBITS | - SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_NOREPOSITION | - SWP_NOSENDCHANGING | SWP_NOSIZE | SWP_NOZORDER); -} - void WindowWin::SetIsAlwaysOnTop(bool always_on_top) { ::SetWindowPos(GetNativeView(), always_on_top ? HWND_TOPMOST : HWND_NOTOPMOST, @@ -509,17 +465,14 @@ void WindowWin::FrameTypeChanged() { // DWMNCRP_ENABLED is used for the native frame case. _DISABLED means the // DWM doesn't render glass, and so is used in the custom frame case. DWMNCRENDERINGPOLICY policy = - GetWindow()->non_client_view()->UseNativeFrame() ? DWMNCRP_ENABLED - : DWMNCRP_DISABLED; + delegate_->IsUsingNativeFrame() ? DWMNCRP_ENABLED : DWMNCRP_DISABLED; DwmSetWindowAttribute(GetNativeView(), DWMWA_NCRENDERING_POLICY, &policy, sizeof(DWMNCRENDERINGPOLICY)); } // Send a frame change notification, since the non-client metrics have // changed. - SetWindowPos(NULL, 0, 0, 0, 0, - SWP_FRAMECHANGED | SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | - SWP_NOOWNERZORDER | SWP_NOACTIVATE); + SendFrameChanged(GetNativeView()); // Update the non-client view with the correct frame view for the active frame // type. @@ -551,7 +504,6 @@ WindowWin::WindowWin(WindowDelegate* window_delegate) focus_on_creation_(true), restored_enabled_(false), fullscreen_(false), - window_closed_(false), is_active_(false), lock_updates_(false), saved_window_style_(0), @@ -587,7 +539,7 @@ void WindowWin::Init(gfx::NativeView parent, const gfx::Rect& bounds) { gfx::Insets WindowWin::GetClientAreaInsets() const { // Returning an empty Insets object causes the default handling in // WidgetWin::OnNCCalcSize() to be invoked. - if (GetWindow()->non_client_view()->UseNativeFrame()) + if (delegate_->IsUsingNativeFrame()) return gfx::Insets(); if (IsMaximized()) { @@ -619,8 +571,7 @@ int WindowWin::GetShowState() const { // WindowWin, WidgetWin overrides: void WindowWin::OnActivate(UINT action, BOOL minimized, HWND window) { - if (action == WA_INACTIVE) - SaveWindowPosition(); + delegate_->OnNativeWindowActivationChanged(action == WA_ACTIVE); } void WindowWin::OnActivateApp(BOOL active, DWORD thread_id) { @@ -653,8 +604,20 @@ void WindowWin::OnCommand(UINT notification_code, int command_id, HWND window) { } void WindowWin::OnDestroy() { - delegate_->OnWindowDestroying(); + delegate_->OnNativeWindowDestroying(); + RestoreEnabledIfNecessary(); + + // If the user activates another app after opening us, then comes back and + // 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. + HWND owner = GetOwner(GetNativeView()); + if (owner && GetNativeView() == GetForegroundWindow() && + IsWindowVisible(owner)) { + SetForegroundWindow(owner); + } + WidgetWin::OnDestroy(); } @@ -671,28 +634,21 @@ LRESULT WindowWin::OnDwmCompositionChanged(UINT msg, WPARAM w_param, } void WindowWin::OnFinalMessage(HWND window) { - delegate_->OnWindowDestroyed(); + delegate_->OnNativeWindowDestroyed(); WidgetWin::OnFinalMessage(window); } void WindowWin::OnGetMinMaxInfo(MINMAXINFO* minmax_info) { - gfx::Size min_window_size(GetWindow()->non_client_view()->GetMinimumSize()); + gfx::Size min_window_size(delegate_->GetMinimumSize()); minmax_info->ptMinTrackSize.x = min_window_size.width(); minmax_info->ptMinTrackSize.y = min_window_size.height(); WidgetWin::OnGetMinMaxInfo(minmax_info); } -namespace { -static void EnableMenuItem(HMENU menu, UINT command, bool enabled) { - UINT flags = MF_BYCOMMAND | (enabled ? MF_ENABLED : MF_DISABLED | MF_GRAYED); - EnableMenuItem(menu, command, flags); -} -} // namespace - void WindowWin::OnInitMenu(HMENU menu) { // We only need to manually enable the system menu if we're not using a native // frame. - if (GetWindow()->non_client_view()->UseNativeFrame()) + if (delegate_->IsUsingNativeFrame()) WidgetWin::OnInitMenu(menu); bool is_fullscreen = IsFullscreen(); @@ -716,7 +672,7 @@ void WindowWin::OnInitMenu(HMENU menu) { LRESULT WindowWin::OnMouseLeave(UINT message, WPARAM w_param, LPARAM l_param) { // We only need to manually track WM_MOUSELEAVE messages between the client // and non-client area when we're not using the native frame. - if (GetWindow()->non_client_view()->UseNativeFrame()) { + if (delegate_->IsUsingNativeFrame()) { SetMsgHandled(FALSE); return 0; } @@ -829,7 +785,7 @@ LRESULT WindowWin::OnNCCalcSize(BOOL mode, LPARAM l_param) { if (EdgeHasTopmostAutoHideTaskbar(ABE_LEFT, monitor)) client_rect->left += kAutoHideTaskbarThicknessPx; if (EdgeHasTopmostAutoHideTaskbar(ABE_TOP, monitor)) { - if (GetWindow()->non_client_view()->UseNativeFrame()) { + if (delegate_->IsUsingNativeFrame()) { // Tricky bit. Due to a bug in DwmDefWindowProc()'s handling of // WM_NCHITTEST, having any nonclient area atop the window causes the // caption buttons to draw onscreen but not respond to mouse @@ -872,8 +828,7 @@ LRESULT WindowWin::OnNCHitTest(const CPoint& point) { // provides any of the non-client area. CPoint temp = point; MapWindowPoints(HWND_DESKTOP, GetNativeView(), &temp, 1); - int component = - GetWindow()->non_client_view()->NonClientHitTest(gfx::Point(temp)); + int component = delegate_->GetNonClientComponent(gfx::Point(temp)); if (component != HTNOWHERE) return component; @@ -887,8 +842,7 @@ LRESULT WindowWin::OnNCMouseRange(UINT message, LPARAM l_param) { // When we're using a native frame, window controls work without us // interfering. - if (message == WM_NCLBUTTONDOWN && - !GetWindow()->non_client_view()->UseNativeFrame()) { + if (message == WM_NCLBUTTONDOWN && !delegate_->IsUsingNativeFrame()) { switch (w_param) { case HTCLOSE: case HTMINBUTTON: @@ -943,14 +897,14 @@ LRESULT WindowWin::OnNCMouseRange(UINT message, void WindowWin::OnNCPaint(HRGN rgn) { // When using a custom frame, we want to avoid calling DefWindowProc() since // that may render artifacts. - SetMsgHandled(!GetWindow()->non_client_view()->UseNativeFrame()); + SetMsgHandled(!delegate_->IsUsingNativeFrame()); } LRESULT WindowWin::OnNCUAHDrawCaption(UINT msg, WPARAM w_param, LPARAM l_param) { // See comment in widget_win.h at the definition of WM_NCUAHDRAWCAPTION for // an explanation about why we need to handle this message. - SetMsgHandled(!GetWindow()->non_client_view()->UseNativeFrame()); + SetMsgHandled(!delegate_->IsUsingNativeFrame()); return 0; } @@ -958,7 +912,7 @@ LRESULT WindowWin::OnNCUAHDrawFrame(UINT msg, WPARAM w_param, LPARAM l_param) { // See comment in widget_win.h at the definition of WM_NCUAHDRAWCAPTION for // an explanation about why we need to handle this message. - SetMsgHandled(!GetWindow()->non_client_view()->UseNativeFrame()); + SetMsgHandled(!delegate_->IsUsingNativeFrame()); return 0; } @@ -989,10 +943,7 @@ void WindowWin::OnSettingChange(UINT flags, const wchar_t* section) { } void WindowWin::OnSize(UINT size_param, const CSize& new_size) { - // Don't no-op if the new_size matches current size. If our normal bounds - // and maximized bounds are the same, then we need to layout (because we - // layout differently when maximized). - SaveWindowPosition(); + delegate_->OnNativeWindowBoundsChanged(); RedrawWindow(GetNativeView(), NULL, NULL, RDW_INVALIDATE | RDW_ALLCHILDREN); // ResetWindowRegion is going to trigger WM_NCPAINT. By doing it after we've @@ -1010,7 +961,7 @@ void WindowWin::OnSysCommand(UINT notification_code, CPoint click) { ((notification_code & sc_mask) == SC_MOVE) || ((notification_code & sc_mask) == SC_MAXIMIZE))) return; - if (!GetWindow()->non_client_view()->UseNativeFrame()) { + if (!delegate_->IsUsingNativeFrame()) { if ((notification_code & sc_mask) == SC_MINIMIZE || (notification_code & sc_mask) == SC_MAXIMIZE || (notification_code & sc_mask) == SC_RESTORE) { @@ -1039,13 +990,11 @@ void WindowWin::OnSysCommand(UINT notification_code, CPoint click) { return; } - // First see if the delegate can handle it. - if (GetWindow()->window_delegate()->ExecuteWindowsCommand(notification_code)) - return; - - // Use the default implementation for any other command. - DefWindowProc(GetNativeView(), WM_SYSCOMMAND, notification_code, - MAKELPARAM(click.x, click.y)); + // If the delegate can't handle it, the system implementation will be called. + if (!delegate_->ExecuteCommand(notification_code)) { + DefWindowProc(GetNativeView(), WM_SYSCOMMAND, notification_code, + MAKELPARAM(click.x, click.y)); + } } void WindowWin::OnWindowPosChanging(WINDOWPOS* window_pos) { @@ -1122,6 +1071,17 @@ void WindowWin::OnWindowPosChanging(WINDOWPOS* window_pos) { //////////////////////////////////////////////////////////////////////////////// // WindowWin, NativeWindow implementation: +gfx::Rect WindowWin::GetRestoredBounds() const { + // If we're in fullscreen mode, we've changed the normal bounds to the monitor + // rect, so return the saved bounds instead. + if (IsFullscreen()) + return gfx::Rect(saved_window_info_.window_rect); + + gfx::Rect bounds; + GetWindowBoundsAndMaximizedState(&bounds, NULL); + return bounds; +} + void WindowWin::ShowNativeWindow(ShowState state) { Show(state == SHOW_MAXIMIZED ? SW_SHOWMAXIMIZED : GetShowState()); } @@ -1144,6 +1104,36 @@ void WindowWin::CenterWindow(const gfx::Size& size) { ui::CenterAndSizeWindow(parent, GetNativeView(), size, false); } +void WindowWin::GetWindowBoundsAndMaximizedState(gfx::Rect* bounds, + bool* maximized) const { + WINDOWPLACEMENT wp; + wp.length = sizeof(wp); + const bool succeeded = !!GetWindowPlacement(GetNativeView(), &wp); + DCHECK(succeeded); + + if (bounds != NULL) { + MONITORINFO mi; + mi.cbSize = sizeof(mi); + const bool succeeded = !!GetMonitorInfo( + MonitorFromWindow(GetNativeView(), MONITOR_DEFAULTTONEAREST), &mi); + DCHECK(succeeded); + *bounds = gfx::Rect(wp.rcNormalPosition); + // Convert normal position from workarea coordinates to screen coordinates. + bounds->Offset(mi.rcWork.left - mi.rcMonitor.left, + mi.rcWork.top - mi.rcMonitor.top); + } + + if (maximized != NULL) + *maximized = (wp.showCmd == SW_SHOWMAXIMIZED); +} + +void WindowWin::EnableClose(bool enable) { + // Disable the native frame's close button regardless of whether or not the + // native frame is in use, since this also affects the system menu. + EnableMenuItem(GetSystemMenu(GetNativeView(), false), SC_CLOSE, enable); + SendFrameChanged(GetNativeView()); +} + void WindowWin::SetWindowTitle(const std::wstring& title) { SetWindowText(GetNativeView(), title.c_str()); SetAccessibleName(title); @@ -1261,7 +1251,7 @@ DWORD WindowWin::CalculateWindowStyle() { } else if (can_resize) { window_styles |= WS_OVERLAPPED | WS_THICKFRAME; } - if (GetWindow()->window_delegate()->AsDialogDelegate()) { + if (delegate_->IsDialogBox()) { window_styles |= DS_MODALFRAME; // NOTE: Turning this off means we lose the close button, which is bad. // Turning it on though means the user can maximize or size the window @@ -1273,24 +1263,7 @@ DWORD WindowWin::CalculateWindowStyle() { } DWORD WindowWin::CalculateWindowExStyle() { - DWORD window_ex_styles = 0; - if (GetWindow()->window_delegate()->AsDialogDelegate()) - window_ex_styles |= WS_EX_DLGMODALFRAME; - return window_ex_styles; -} - -void WindowWin::SaveWindowPosition() { - // The window delegate does the actual saving for us. It seems like (judging - // by go/crash) that in some circumstances we can end up here after - // WM_DESTROY, at which point the window delegate is likely gone. So just - // bail. - if (!GetWindow()->window_delegate()) - return; - - bool maximized; - gfx::Rect bounds; - GetWindowBoundsAndMaximizedState(&bounds, &maximized); - GetWindow()->window_delegate()->SaveWindowPlacement(bounds, maximized); + return delegate_->IsDialogBox() ? WS_EX_DLGMODALFRAME : 0; } void WindowWin::LockUpdates() { @@ -1307,7 +1280,7 @@ void WindowWin::UnlockUpdates() { void WindowWin::ResetWindowRegion(bool force) { // A native frame uses the native window region, and we don't want to mess // with it. - if (GetWindow()->non_client_view()->UseNativeFrame()) { + if (delegate_->IsUsingNativeFrame()) { if (force) SetWindowRgn(NULL, TRUE); return; @@ -1360,29 +1333,6 @@ void WindowWin::ExecuteSystemMenuCommand(int command) { SendMessage(GetNativeView(), WM_SYSCOMMAND, command, 0); } -void WindowWin::GetWindowBoundsAndMaximizedState(gfx::Rect* bounds, - bool* maximized) const { - WINDOWPLACEMENT wp; - wp.length = sizeof(wp); - const bool succeeded = !!GetWindowPlacement(GetNativeView(), &wp); - DCHECK(succeeded); - - if (bounds != NULL) { - MONITORINFO mi; - mi.cbSize = sizeof(mi); - const bool succeeded = !!GetMonitorInfo( - MonitorFromWindow(GetNativeView(), MONITOR_DEFAULTTONEAREST), &mi); - DCHECK(succeeded); - *bounds = gfx::Rect(wp.rcNormalPosition); - // Convert normal position from workarea coordinates to screen coordinates. - bounds->Offset(mi.rcWork.left - mi.rcMonitor.left, - mi.rcWork.top - mi.rcMonitor.top); - } - - if (maximized != NULL) - *maximized = (wp.showCmd == SW_SHOWMAXIMIZED); -} - void WindowWin::InitClass() { static bool initialized = false; if (!initialized) { diff --git a/views/window/window_win.h b/views/window/window_win.h index fcb7a5d..9c74f75 100644 --- a/views/window/window_win.h +++ b/views/window/window_win.h @@ -55,8 +55,6 @@ class WindowWin : public WidgetWin, } // Overridden from Window: - virtual gfx::Rect GetBounds() const OVERRIDE; - virtual gfx::Rect GetNormalBounds() const OVERRIDE; virtual void SetWindowBounds(const gfx::Rect& bounds, gfx::NativeWindow other_window) OVERRIDE; virtual void HideWindow() OVERRIDE; @@ -66,7 +64,6 @@ class WindowWin : public WidgetWin, virtual void PopForceHidden() OVERRIDE; virtual void Activate() OVERRIDE; virtual void Deactivate() OVERRIDE; - virtual void Close() OVERRIDE; virtual void Maximize() OVERRIDE; virtual void Minimize() OVERRIDE; virtual void Restore() OVERRIDE; @@ -77,7 +74,6 @@ class WindowWin : public WidgetWin, virtual void SetFullscreen(bool fullscreen) OVERRIDE; virtual bool IsFullscreen() const OVERRIDE; virtual void SetUseDragFrame(bool use_drag_frame) OVERRIDE; - virtual void EnableClose(bool enable) OVERRIDE; virtual void SetIsAlwaysOnTop(bool always_on_top) OVERRIDE; virtual NonClientFrameView* CreateFrameViewForWindow() OVERRIDE; virtual void UpdateFrameAfterFrameChange() OVERRIDE; @@ -158,9 +154,13 @@ class WindowWin : public WidgetWin, virtual const Window* GetWindow() const OVERRIDE { return this; } // Overridden from NativeWindow: - virtual void ShowNativeWindow(ShowState state); + virtual gfx::Rect GetRestoredBounds() const OVERRIDE; + virtual void ShowNativeWindow(ShowState state) OVERRIDE; virtual void BecomeModal() OVERRIDE; virtual void CenterWindow(const gfx::Size& size) OVERRIDE; + virtual void GetWindowBoundsAndMaximizedState(gfx::Rect* bounds, + bool* maximized) const OVERRIDE; + virtual void EnableClose(bool enable) OVERRIDE; virtual void SetWindowTitle(const std::wstring& title) OVERRIDE; virtual void SetWindowIcons(const SkBitmap& window_icon, const SkBitmap& app_icon) OVERRIDE; @@ -192,9 +192,6 @@ class WindowWin : public WidgetWin, DWORD CalculateWindowStyle(); DWORD CalculateWindowExStyle(); - // Asks the delegate if any to save the window's location and size. - void SaveWindowPosition(); - // Lock or unlock the window from being able to redraw itself in response to // updates to its invalid region. class ScopedRedrawLock; @@ -222,11 +219,6 @@ class WindowWin : public WidgetWin, // Executes the specified SC_command. void ExecuteSystemMenuCommand(int command); - // Returns the normal bounds of the window in screen coordinates and - // whether the window is maximized. The arguments can be NULL. - void GetWindowBoundsAndMaximizedState(gfx::Rect* bounds, - bool* maximized) const; - // Static resource initialization. static void InitClass(); enum ResizeCursor { @@ -251,9 +243,6 @@ class WindowWin : public WidgetWin, // Saved window information from before entering fullscreen mode. SavedWindowInfo saved_window_info_; - // Set to true if the window is in the process of closing . - bool window_closed_; - // True if this window is the active top level window. bool is_active_; |