diff options
author | pkasting@chromium.org <pkasting@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-03-04 00:36:48 +0000 |
---|---|---|
committer | pkasting@chromium.org <pkasting@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-03-04 00:36:48 +0000 |
commit | 3fbfa3fb89128ea61adf02c63f2cf4e1121c7933 (patch) | |
tree | 6d8d30b009c8e13336c1f5578c32fea90d494eaf /chrome | |
parent | b9636005dd6f235dfb4fa4ea3a83df284341667d (diff) | |
download | chromium_src-3fbfa3fb89128ea61adf02c63f2cf4e1121c7933.zip chromium_src-3fbfa3fb89128ea61adf02c63f2cf4e1121c7933.tar.gz chromium_src-3fbfa3fb89128ea61adf02c63f2cf4e1121c7933.tar.bz2 |
Make Chromium windows not hide auto-hide taskbars.
There are a few caveats here:
* On Aero glass, if the auto-hide taskbar is at the top of the screen, we get one row of nonclient pixels along the bottom of the screen (not too noticeable for light-colored pages, looks a bit odd with a dark page). I can't find a way around this.
* Switching between fullscreen and normal mode can leave things a bit confused until you click another app and then reactivate Chromium. This seems to happen with other applications too (e.g. Firefox fullscreen mode) so I'm not too worried.
* Chromium does not deal well with toggling the taskbar's auto-hide setting (or, I think, its position?) unless you restore and remaximize the window. I tried to fix this via modified handling of WM_SETTINGCHANGE but only made things worse and so gave up.
BUG=20
Review URL: http://codereview.chromium.org/28338
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@10845 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r-- | chrome/browser/views/frame/browser_frame.cc | 58 | ||||
-rw-r--r-- | chrome/browser/views/frame/browser_frame.h | 2 | ||||
-rw-r--r-- | chrome/browser/views/frame/glass_browser_frame_view.cc | 27 | ||||
-rw-r--r-- | chrome/browser/views/frame/glass_browser_frame_view.h | 2 | ||||
-rw-r--r-- | chrome/browser/views/frame/opaque_browser_frame_view.cc | 17 | ||||
-rw-r--r-- | chrome/common/win_util.cc | 12 | ||||
-rw-r--r-- | chrome/common/win_util.h | 7 | ||||
-rw-r--r-- | chrome/views/window.cc | 45 |
8 files changed, 117 insertions, 53 deletions
diff --git a/chrome/browser/views/frame/browser_frame.cc b/chrome/browser/views/frame/browser_frame.cc index c318f37..a264908c 100644 --- a/chrome/browser/views/frame/browser_frame.cc +++ b/chrome/browser/views/frame/browser_frame.cc @@ -116,22 +116,49 @@ LRESULT BrowserFrame::OnNCCalcSize(BOOL mode, LPARAM l_param) { // We don't adjust the client area unless we're a tabbed browser window and // are using the native frame. if (!non_client_view_->UseNativeFrame() || - !browser_view_->IsBrowserTypeNormal() || !mode) { + !browser_view_->IsBrowserTypeNormal()) { return Window::OnNCCalcSize(mode, l_param); } - // In fullscreen mode, we make the whole window client area. - if (!browser_view_->IsFullscreen()) { - NCCALCSIZE_PARAMS* params = reinterpret_cast<NCCALCSIZE_PARAMS*>(l_param); - int border_thickness = GetSystemMetrics(SM_CXSIZEFRAME); - params->rgrc[0].left += (border_thickness - kClientEdgeThickness); - params->rgrc[0].right -= (border_thickness - kClientEdgeThickness); - params->rgrc[0].bottom -= (border_thickness - kClientEdgeThickness); + RECT* client_rect = mode ? + &reinterpret_cast<NCCALCSIZE_PARAMS*>(l_param)->rgrc[0] : + reinterpret_cast<RECT*>(l_param); + int border_thickness = 0; + if (browser_view_->IsMaximized()) { + // Make the maximized mode client rect fit the screen exactly, by + // subtracting the border Windows automatically adds for maximized mode. + border_thickness = GetSystemMetrics(SM_CXSIZEFRAME); + // Find all auto-hide taskbars along the screen edges and adjust in by the + // thickness of the auto-hide taskbar on each such edge, so the window isn't + // treated as a "fullscreen app", which would cause the taskbars to + // disappear. + HMONITOR monitor = MonitorFromWindow(GetHWND(), MONITOR_DEFAULTTONEAREST); + if (win_util::EdgeHasAutoHideTaskbar(ABE_LEFT, monitor)) + client_rect->left += win_util::kAutoHideTaskbarThicknessPx; + if (win_util::EdgeHasAutoHideTaskbar(ABE_RIGHT, monitor)) + client_rect->right -= win_util::kAutoHideTaskbarThicknessPx; + if (win_util::EdgeHasAutoHideTaskbar(ABE_BOTTOM, monitor)) { + client_rect->bottom -= win_util::kAutoHideTaskbarThicknessPx; + } else if (win_util::EdgeHasAutoHideTaskbar(ABE_TOP, monitor)) { + // 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 hover/clicks. + // So for a taskbar at the screen top, we can't push the client_rect->top + // down; instead, we move the bottom up by one pixel, which is the + // smallest change we can make and still get a client area less than the + // screen size. This is visibly ugly, but there seems to be no better + // solution. + --client_rect->bottom; + } + } else if (!browser_view_->IsFullscreen()) { + // We draw our own client edge over part of the default frame would be. + border_thickness = GetSystemMetrics(SM_CXSIZEFRAME) - kClientEdgeThickness; } + client_rect->left += border_thickness; + client_rect->right -= border_thickness; + client_rect->bottom -= border_thickness; UpdateDWMFrame(); - - SetMsgHandled(TRUE); return 0; } @@ -140,9 +167,8 @@ LRESULT BrowserFrame::OnNCHitTest(const CPoint& pt) { if (non_client_view_->UseNativeFrame()) { LRESULT result; if (DwmDefWindowProc(GetHWND(), WM_NCHITTEST, 0, MAKELPARAM(pt.x, pt.y), - &result)) { + &result)) return result; - } } return Window::OnNCHitTest(pt); } @@ -179,12 +205,16 @@ void BrowserFrame::UpdateDWMFrame() { // because the GDI-drawn text in the web content composited over it will // become semi-transparent over any glass area. MARGINS margins = { 0 }; - if (!browser_view_->IsFullscreen()) { + if (browser_view_->CanCurrentlyResize()) { margins.cxLeftWidth = kClientEdgeThickness + 1; margins.cxRightWidth = kClientEdgeThickness + 1; + margins.cyBottomHeight = kClientEdgeThickness + 1; + } + // In maximized mode, we only have a titlebar strip of glass, no side/bottom + // borders. + if (!browser_view_->IsFullscreen()) { margins.cyTopHeight = GetBoundsForTabStrip(browser_view_->tabstrip()).bottom(); - margins.cyBottomHeight = kClientEdgeThickness + 1; } DwmExtendFrameIntoClientArea(GetHWND(), &margins); } diff --git a/chrome/browser/views/frame/browser_frame.h b/chrome/browser/views/frame/browser_frame.h index c7efcab..13dace7 100644 --- a/chrome/browser/views/frame/browser_frame.h +++ b/chrome/browser/views/frame/browser_frame.h @@ -55,9 +55,9 @@ class BrowserFrame : public views::Window { // Overridden from views::WidgetWin: virtual bool AcceleratorPressed(views::Accelerator* accelerator); virtual bool GetAccelerator(int cmd_id, views::Accelerator* accelerator); - virtual void OnInitMenuPopup(HMENU menu, UINT position, BOOL is_system_menu); virtual void OnEnterSizeMove(); virtual void OnEndSession(BOOL ending, UINT logoff); + virtual void OnInitMenuPopup(HMENU menu, UINT position, BOOL is_system_menu); virtual LRESULT OnMouseActivate(HWND window, UINT hittest_code, UINT message); diff --git a/chrome/browser/views/frame/glass_browser_frame_view.cc b/chrome/browser/views/frame/glass_browser_frame_view.cc index 54982d7..8ca20b0 100644 --- a/chrome/browser/views/frame/glass_browser_frame_view.cc +++ b/chrome/browser/views/frame/glass_browser_frame_view.cc @@ -178,10 +178,10 @@ gfx::Rect GlassBrowserFrameView::GetWindowBoundsForClientBounds( gfx::Point GlassBrowserFrameView::GetSystemMenuPoint() const { gfx::Point system_menu_point; if (browser_view_->IsBrowserTypeNormal()) { - // The maximized mode bit here is because in maximized mode the frame edge - // and the client edge are both offscreen, whereas in the opaque frame - // (where we don't do this trick) maximized windows have no client edge and - // only the frame edge is offscreen. + // The maximized mode bit here is because in maximized mode there is no + // client edge, but in restored mode there is one, and unlike in the opaque + // frame we don't have a convenient function to get its coordinate (since + // FrameBorderThickness() won't do what we want). system_menu_point.SetPoint(NonClientBorderThickness() - (frame_->IsMaximized() ? 0 : kClientEdgeThickness), NonClientTopBorderHeight() + browser_view_->GetTabStripHeight() - @@ -224,7 +224,8 @@ void GlassBrowserFrameView::Paint(ChromeCanvas* canvas) { PaintDistributorLogo(canvas); PaintToolbarBackground(canvas); PaintOTRAvatar(canvas); - PaintClientEdge(canvas); + if (!frame_->IsMaximized()) + PaintRestoredClientEdge(canvas); } void GlassBrowserFrameView::Layout() { @@ -237,16 +238,22 @@ void GlassBrowserFrameView::Layout() { // GlassBrowserFrameView, private: int GlassBrowserFrameView::FrameBorderThickness() const { - return GetSystemMetrics(SM_CXSIZEFRAME); + return browser_view_->CanCurrentlyResize() ? + GetSystemMetrics(SM_CXSIZEFRAME) : 0; } int GlassBrowserFrameView::NonClientBorderThickness() const { - return kNonClientBorderThickness; + return browser_view_->CanCurrentlyResize() ? kNonClientBorderThickness : 0; } int GlassBrowserFrameView::NonClientTopBorderHeight() const { - return FrameBorderThickness() + - (frame_->IsMaximized() ? 0 : kNonClientRestoredExtraThickness); + if (browser_view_->IsFullscreen()) + return 0; + // We'd like to use FrameBorderThickness() here, but the maximized Aero glass + // frame has a 0 frame border around most edges and a CXSIZEFRAME-thick border + // at the top (see AeroGlassFrame::OnGetMinMaxInfo()). + return GetSystemMetrics(SM_CXSIZEFRAME) + + (browser_view_->IsMaximized() ? 0 : kNonClientRestoredExtraThickness); } void GlassBrowserFrameView::PaintDistributorLogo(ChromeCanvas* canvas) { @@ -294,7 +301,7 @@ void GlassBrowserFrameView::PaintOTRAvatar(ChromeCanvas* canvas) { otr_avatar_bounds_.width(), otr_avatar_bounds_.height(), false); } -void GlassBrowserFrameView::PaintClientEdge(ChromeCanvas* canvas) { +void GlassBrowserFrameView::PaintRestoredClientEdge(ChromeCanvas* canvas) { // The client edges start below the toolbar upper corner images regardless // of how tall the toolbar itself is. int client_area_top = diff --git a/chrome/browser/views/frame/glass_browser_frame_view.h b/chrome/browser/views/frame/glass_browser_frame_view.h index f325dde..edaed89 100644 --- a/chrome/browser/views/frame/glass_browser_frame_view.h +++ b/chrome/browser/views/frame/glass_browser_frame_view.h @@ -54,7 +54,7 @@ class GlassBrowserFrameView : public BrowserNonClientFrameView { void PaintDistributorLogo(ChromeCanvas* canvas); void PaintToolbarBackground(ChromeCanvas* canvas); void PaintOTRAvatar(ChromeCanvas* canvas); - void PaintClientEdge(ChromeCanvas* canvas); + void PaintRestoredClientEdge(ChromeCanvas* canvas); // Layout various sub-components of this view. void LayoutDistributorLogo(); diff --git a/chrome/browser/views/frame/opaque_browser_frame_view.cc b/chrome/browser/views/frame/opaque_browser_frame_view.cc index 98a71c3..a908d7f 100644 --- a/chrome/browser/views/frame/opaque_browser_frame_view.cc +++ b/chrome/browser/views/frame/opaque_browser_frame_view.cc @@ -505,7 +505,7 @@ void OpaqueBrowserFrameView::GetWindowMask(const gfx::Size& size, gfx::Path* window_mask) { DCHECK(window_mask); - if (browser_view_->IsFullscreen()) + if (!browser_view_->CanCurrentlyResize()) return; // Redefine the window visible region for the new size. @@ -647,10 +647,7 @@ SkBitmap OpaqueBrowserFrameView::GetFavIconForTabIconView() { // OpaqueBrowserFrameView, private: int OpaqueBrowserFrameView::FrameBorderThickness() const { - if (browser_view_->IsFullscreen()) - return 0; - return frame_->IsMaximized() ? - GetSystemMetrics(SM_CXSIZEFRAME) : kFrameBorderThickness; + return browser_view_->CanCurrentlyResize() ? kFrameBorderThickness : 0; } int OpaqueBrowserFrameView::TopResizeHeight() const { @@ -918,13 +915,11 @@ void OpaqueBrowserFrameView::LayoutWindowControls() { // button to the screen corner to obey Fitts' Law. int right_extra_width = is_maximized ? (kFrameBorderThickness - kFrameShadowThickness) : 0; - int right_spacing = is_maximized ? - (GetSystemMetrics(SM_CXSIZEFRAME) + right_extra_width) : frame_thickness; gfx::Size close_button_size = close_button_->GetPreferredSize(); - close_button_->SetBounds(width() - close_button_size.width() - right_spacing, - caption_y, - close_button_size.width() + right_extra_width, - close_button_size.height() + top_extra_height); + close_button_->SetBounds(width() - close_button_size.width() - + right_extra_width - frame_thickness, caption_y, + close_button_size.width() + right_extra_width, + close_button_size.height() + top_extra_height); // When the window is restored, we show a maximized button; otherwise, we show // a restore button. diff --git a/chrome/common/win_util.cc b/chrome/common/win_util.cc index 7437031..50850d1 100644 --- a/chrome/common/win_util.cc +++ b/chrome/common/win_util.cc @@ -28,6 +28,8 @@ namespace win_util { +const int kAutoHideTaskbarThicknessPx = 2; + namespace { // Enforce visible dialog box. @@ -624,6 +626,16 @@ void CenterAndSizeWindow(HWND parent, HWND window, const SIZE& pref, } } +bool EdgeHasAutoHideTaskbar(UINT edge, HMONITOR monitor) { + APPBARDATA taskbar_data = { 0 }; + taskbar_data.cbSize = sizeof APPBARDATA; + taskbar_data.uEdge = edge; + HWND taskbar = reinterpret_cast<HWND>(SHAppBarMessage(ABM_GETAUTOHIDEBAR, + &taskbar_data)); + return ::IsWindow(taskbar) && + (MonitorFromWindow(taskbar, MONITOR_DEFAULTTONEAREST) == monitor); +} + HANDLE GetSectionFromProcess(HANDLE section, HANDLE process, bool read_only) { HANDLE valid_section = NULL; DWORD access = STANDARD_RIGHTS_REQUIRED | FILE_MAP_READ; diff --git a/chrome/common/win_util.h b/chrome/common/win_util.h index c93b098..8e703cb 100644 --- a/chrome/common/win_util.h +++ b/chrome/common/win_util.h @@ -211,6 +211,10 @@ void AdjustWindowToFit(HWND hwnd); void CenterAndSizeWindow(HWND parent, HWND window, const SIZE& pref, bool pref_is_client); +// Returns true if edge |edge| (one of ABE_LEFT, TOP, RIGHT, or BOTTOM) of +// monitor |monitor| has an auto-hiding taskbar. +bool EdgeHasAutoHideTaskbar(UINT edge, HMONITOR monitor); + // Duplicates a section handle from another process to the current process. // Returns the new valid handle if the function succeed. NULL otherwise. HANDLE GetSectionFromProcess(HANDLE section, HANDLE process, bool read_only); @@ -274,6 +278,9 @@ int MessageBox(HWND hwnd, // Returns the system set window title font. ChromeFont GetWindowTitleFont(); +// The thickness of an auto-hide taskbar in pixels. +extern const int kAutoHideTaskbarThicknessPx; + } // namespace win_util #endif // CHROME_COMMON_WIN_UTIL_H_ diff --git a/chrome/views/window.cc b/chrome/views/window.cc index d0875d8..80c6f31 100644 --- a/chrome/views/window.cc +++ b/chrome/views/window.cc @@ -561,8 +561,32 @@ LRESULT Window::OnNCCalcSize(BOOL mode, LPARAM l_param) { if (non_client_view_->UseNativeFrame()) return WidgetWin::OnNCCalcSize(mode, l_param); + RECT* client_rect = mode ? + &reinterpret_cast<NCCALCSIZE_PARAMS*>(l_param)->rgrc[0] : + reinterpret_cast<RECT*>(l_param); + if (IsMaximized()) { + // Make the maximized mode client rect fit the screen exactly, by + // subtracting the border Windows automatically adds for maximized mode. + int border_thickness = GetSystemMetrics(SM_CXSIZEFRAME); + InflateRect(client_rect, -border_thickness, -border_thickness); + + // Find all auto-hide taskbars along the screen edges and adjust in by the + // thickness of the auto-hide taskbar on each such edge, so the window isn't + // treated as a "fullscreen app", which would cause the taskbars to + // disappear. + HMONITOR monitor = MonitorFromWindow(GetHWND(), MONITOR_DEFAULTTONEAREST); + if (win_util::EdgeHasAutoHideTaskbar(ABE_LEFT, monitor)) + client_rect->left += win_util::kAutoHideTaskbarThicknessPx; + if (win_util::EdgeHasAutoHideTaskbar(ABE_TOP, monitor)) + client_rect->top += win_util::kAutoHideTaskbarThicknessPx; + if (win_util::EdgeHasAutoHideTaskbar(ABE_RIGHT, monitor)) + client_rect->right -= win_util::kAutoHideTaskbarThicknessPx; + if (win_util::EdgeHasAutoHideTaskbar(ABE_BOTTOM, monitor)) + client_rect->bottom -= win_util::kAutoHideTaskbarThicknessPx; + } + // We need to repaint all when the window bounds change. - return WVR_REDRAW; + return mode ? WVR_REDRAW : 0; } LRESULT Window::OnNCHitTest(const CPoint& point) { @@ -1077,21 +1101,10 @@ void Window::ResetWindowRegion(bool force) { CRect window_rect; GetWindowRect(&window_rect); HRGN new_region; - if (IsMaximized()) { - HMONITOR monitor = MonitorFromWindow(GetHWND(), MONITOR_DEFAULTTONEAREST); - MONITORINFO mi; - mi.cbSize = sizeof mi; - GetMonitorInfo(monitor, &mi); - CRect work_rect = mi.rcWork; - work_rect.OffsetRect(-window_rect.left, -window_rect.top); - new_region = CreateRectRgnIndirect(&work_rect); - } else { - gfx::Path window_mask; - non_client_view_->GetWindowMask(gfx::Size(window_rect.Width(), - window_rect.Height()), - &window_mask); - new_region = window_mask.CreateHRGN(); - } + gfx::Path window_mask; + non_client_view_->GetWindowMask( + gfx::Size(window_rect.Width(), window_rect.Height()), &window_mask); + new_region = window_mask.CreateHRGN(); if (current_rgn_result == ERROR || !EqualRgn(current_rgn, new_region)) { // SetWindowRgn takes ownership of the HRGN created by CreateHRGN. |