summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
authorpkasting@chromium.org <pkasting@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-03-04 00:36:48 +0000
committerpkasting@chromium.org <pkasting@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-03-04 00:36:48 +0000
commit3fbfa3fb89128ea61adf02c63f2cf4e1121c7933 (patch)
tree6d8d30b009c8e13336c1f5578c32fea90d494eaf /chrome
parentb9636005dd6f235dfb4fa4ea3a83df284341667d (diff)
downloadchromium_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.cc58
-rw-r--r--chrome/browser/views/frame/browser_frame.h2
-rw-r--r--chrome/browser/views/frame/glass_browser_frame_view.cc27
-rw-r--r--chrome/browser/views/frame/glass_browser_frame_view.h2
-rw-r--r--chrome/browser/views/frame/opaque_browser_frame_view.cc17
-rw-r--r--chrome/common/win_util.cc12
-rw-r--r--chrome/common/win_util.h7
-rw-r--r--chrome/views/window.cc45
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.