diff options
author | ben@chromium.org <ben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-10-13 17:25:36 +0000 |
---|---|---|
committer | ben@chromium.org <ben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-10-13 17:25:36 +0000 |
commit | 31d1af421bb4e710839e7c8b0a89e814593c0848 (patch) | |
tree | b5f06d2f49e40ddfcc11467559ba0dba1e80aca0 /chrome | |
parent | f808ee797b9183170f82cb6faa15988047d0bf2b (diff) | |
download | chromium_src-31d1af421bb4e710839e7c8b0a89e814593c0848.zip chromium_src-31d1af421bb4e710839e7c8b0a89e814593c0848.tar.gz chromium_src-31d1af421bb4e710839e7c8b0a89e814593c0848.tar.bz2 |
Assorted improvements to window maximization and flicker on Windows Vista with aero-glass disabled.
http://crbug.com/2488
Review URL: http://codereview.chromium.org/7262
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@3292 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r-- | chrome/browser/views/frame/opaque_non_client_view.cc | 6 | ||||
-rw-r--r-- | chrome/views/custom_frame_window.cc | 101 | ||||
-rw-r--r-- | chrome/views/custom_frame_window.h | 2 |
3 files changed, 98 insertions, 11 deletions
diff --git a/chrome/browser/views/frame/opaque_non_client_view.cc b/chrome/browser/views/frame/opaque_non_client_view.cc index b957549..19628c8 100644 --- a/chrome/browser/views/frame/opaque_non_client_view.cc +++ b/chrome/browser/views/frame/opaque_non_client_view.cc @@ -888,7 +888,7 @@ void OpaqueNonClientView::LayoutWindowControls() { if (frame_->IsMaximized()) { close_button_->GetPreferredSize(&ps); close_button_->SetImageAlignment(ChromeViews::Button::ALIGN_LEFT, - ChromeViews::Button::ALIGN_BOTTOM); + ChromeViews::Button::ALIGN_TOP); close_button_->SetBounds( width() - ps.cx - kWindowControlsRightZoomedOffset, 0, ps.cx + kWindowControlsRightZoomedOffset, @@ -896,13 +896,13 @@ void OpaqueNonClientView::LayoutWindowControls() { restore_button_->GetPreferredSize(&ps); restore_button_->SetImageAlignment(ChromeViews::Button::ALIGN_LEFT, - ChromeViews::Button::ALIGN_BOTTOM); + ChromeViews::Button::ALIGN_TOP); restore_button_->SetBounds(close_button_->x() - ps.cx, 0, ps.cx, ps.cy + kWindowControlsTopZoomedOffset); minimize_button_->GetPreferredSize(&ps); minimize_button_->SetImageAlignment(ChromeViews::Button::ALIGN_LEFT, - ChromeViews::Button::ALIGN_BOTTOM); + ChromeViews::Button::ALIGN_TOP); minimize_button_->SetBounds(restore_button_->x() - ps.cx, 0, ps.cx, ps.cy + kWindowControlsTopZoomedOffset); } else if (frame_->IsMinimized()) { diff --git a/chrome/views/custom_frame_window.cc b/chrome/views/custom_frame_window.cc index a425ea2..b93882e 100644 --- a/chrome/views/custom_frame_window.cc +++ b/chrome/views/custom_frame_window.cc @@ -6,6 +6,7 @@ #include "base/gfx/point.h" #include "base/gfx/size.h" +#include "base/win_util.h" #include "chrome/app/theme/theme_resources.h" #include "chrome/common/gfx/path.h" #include "chrome/common/gfx/chrome_canvas.h" @@ -29,7 +30,7 @@ namespace ChromeViews { // Why would we want such a thing? Well, it turns out Windows has some // "unorthodox" behavior when it comes to painting its non-client areas. // Sadly, the default implementation of some messages, e.g. WM_SETTEXT and -// WM_ENTERMENULOOP actually paint all or parts of the native title bar of the +// WM_SETICON actually paint all or parts of the native title bar of the // application. That's right, they just paint it. They don't go through // WM_NCPAINT or anything like that that we already override. What this means // is that we end up with occasional flicker of bits of the normal Windows @@ -823,6 +824,46 @@ void DefaultNonClientView::InitClass() { } /////////////////////////////////////////////////////////////////////////////// +// NonClientViewLayout + +class NonClientViewLayout : public ChromeViews::LayoutManager { + public: + // The size of the default window border and padding used by Windows Vista + // with DWM disabled when clipping the window for maximized display. + // TODO(beng): figure out how to get this programmatically, since it varies + // with adjustments to the Windows Border/Padding setting. + static const int kBorderAndPadding = 8; + + NonClientViewLayout(ChromeViews::View* child, + ChromeViews::Window* window) + : child_(child), + window_(window) { + } + virtual ~NonClientViewLayout() {} + + // Overridden from ChromeViews::LayoutManager: + virtual void Layout(ChromeViews::View* host) { + int horizontal_border_width = + window_->IsMaximized() ? kBorderAndPadding : 0; + int vertical_border_height = + window_->IsMaximized() ? kBorderAndPadding : 0; + + child_->SetBounds(horizontal_border_width, vertical_border_height, + host->width() - (2 * horizontal_border_width), + host->height() - (2 * vertical_border_height)); + } + virtual void GetPreferredSize(ChromeViews::View* host, CSize* out) { + child_->GetPreferredSize(out); + } + + private: + ChromeViews::View* child_; + ChromeViews::Window* window_; + + DISALLOW_COPY_AND_ASSIGN(NonClientViewLayout); +}; + +/////////////////////////////////////////////////////////////////////////////// // CustomFrameWindow, public: CustomFrameWindow::CustomFrameWindow(WindowDelegate* window_delegate) @@ -852,6 +893,14 @@ void CustomFrameWindow::Init(HWND parent, const gfx::Rect& bounds) { if (!non_client_view_) non_client_view_ = new DefaultNonClientView(this); Window::Init(parent, bounds); + + // Windows Vista non-Aero-glass does wacky things with maximized windows that + // require a special layout manager to compensate for. + if (win_util::GetWinVersion() >= win_util::WINVERSION_VISTA) { + GetRootView()->SetLayoutManager( + new NonClientViewLayout(non_client_view_, this)); + } + ResetWindowRegion(); } @@ -911,6 +960,42 @@ void CustomFrameWindow::SizeWindowToDefault() { /////////////////////////////////////////////////////////////////////////////// // CustomFrameWindow, HWNDViewContainer overrides: +void CustomFrameWindow::OnGetMinMaxInfo(MINMAXINFO* minmax_info) { + // We handle this message so that we can make sure we interact nicely with + // the taskbar on different edges of the screen and auto-hide taskbars. + + HMONITOR primary_monitor = MonitorFromWindow(NULL, MONITOR_DEFAULTTOPRIMARY); + MONITORINFO primary_info; + primary_info.cbSize = sizeof(primary_info); + GetMonitorInfo(primary_monitor, &primary_info); + + minmax_info->ptMaxSize.x = + primary_info.rcWork.right - primary_info.rcWork.left; + minmax_info->ptMaxSize.y = + primary_info.rcWork.bottom - primary_info.rcWork.top; + + HMONITOR target_monitor = + MonitorFromWindow(GetHWND(), MONITOR_DEFAULTTONEAREST); + MONITORINFO target_info; + target_info.cbSize = sizeof(target_info); + GetMonitorInfo(target_monitor, &target_info); + + minmax_info->ptMaxPosition.x = + abs(target_info.rcWork.left - target_info.rcMonitor.left); + minmax_info->ptMaxPosition.y = + abs(target_info.rcWork.top - target_info.rcMonitor.top); + + // Work around task bar auto-hiding. By default the window is sized over the + // top of the un-hide strip, so we adjust the size by a single pixel to make + // it work. Because of the way Windows adjusts the target size rect for non + // primary screens (it's quite daft), we only do this for the primary screen, + // which I think should cover at least 95% of use cases. + if ((target_monitor == primary_monitor) && + EqualRect(&target_info.rcWork, &target_info.rcMonitor)) { + --minmax_info->ptMaxSize.y; + } +} + static void EnableMenuItem(HMENU menu, UINT command, bool enabled) { UINT flags = MF_BYCOMMAND | (enabled ? MF_ENABLED : MF_DISABLED | MF_GRAYED); EnableMenuItem(menu, command, flags); @@ -963,17 +1048,11 @@ LRESULT CustomFrameWindow::OnNCActivate(BOOL active) { // painting operations while the move is in progress. PaintNow(root_view_->GetScheduledPaintRect()); } + return TRUE; } LRESULT CustomFrameWindow::OnNCCalcSize(BOOL mode, LPARAM l_param) { - CRect client_bounds; - if (!mode) { - RECT* rect = reinterpret_cast<RECT*>(l_param); - *rect = non_client_view_->CalculateClientAreaBounds( - rect->right - rect->left, rect->bottom - rect->top).ToRECT(); - return 0; - } // We need to repaint all when the window bounds change. return WVR_REDRAW; } @@ -1165,6 +1244,12 @@ LRESULT CustomFrameWindow::OnSetCursor(HWND window, UINT hittest_code, return 0; } +LRESULT CustomFrameWindow::OnSetIcon(UINT size_type, HICON new_icon) { + ScopedVisibilityRemover remover(GetHWND()); + return DefWindowProc(GetHWND(), WM_SETICON, size_type, + reinterpret_cast<LPARAM>(new_icon)); +} + LRESULT CustomFrameWindow::OnSetText(const wchar_t* text) { ScopedVisibilityRemover remover(GetHWND()); return DefWindowProc(GetHWND(), WM_SETTEXT, NULL, diff --git a/chrome/views/custom_frame_window.h b/chrome/views/custom_frame_window.h index 6b8238b..b1812a0 100644 --- a/chrome/views/custom_frame_window.h +++ b/chrome/views/custom_frame_window.h @@ -48,6 +48,7 @@ class CustomFrameWindow : public Window { virtual void DisableInactiveRendering(bool disable); // Overridden from HWNDViewContainer: + virtual void OnGetMinMaxInfo(MINMAXINFO* minmax_info); virtual void OnInitMenu(HMENU menu); virtual void OnMouseLeave(); virtual LRESULT OnNCActivate(BOOL active); @@ -58,6 +59,7 @@ class CustomFrameWindow : public Window { virtual LRESULT OnNCUAHDrawCaption(UINT msg, WPARAM w_param, LPARAM l_param); virtual LRESULT OnNCUAHDrawFrame(UINT msg, WPARAM w_param, LPARAM l_param); virtual LRESULT OnSetCursor(HWND window, UINT hittest_code, UINT message); + virtual LRESULT OnSetIcon(UINT size_type, HICON new_icon); virtual LRESULT OnSetText(const wchar_t* text); virtual void OnSize(UINT param, const CSize& size); |