diff options
author | msw@chromium.org <msw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-02-03 06:01:16 +0000 |
---|---|---|
committer | msw@chromium.org <msw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-02-03 06:01:16 +0000 |
commit | 75b6805083c906bb17192a738b311bd21791e9f8 (patch) | |
tree | bce38efec20d50a7ef55a694f58036ae365d5e0a | |
parent | 2aa8b71eb688aa13a4f745027bcd4bb726bf6663 (diff) | |
download | chromium_src-75b6805083c906bb17192a738b311bd21791e9f8.zip chromium_src-75b6805083c906bb17192a738b311bd21791e9f8.tar.gz chromium_src-75b6805083c906bb17192a738b311bd21791e9f8.tar.bz2 |
Cross-platform CL to remove app/win/win_util.h&cc and related work.
See Issue 70141 for the full move details; see my inline review comments.
Changes significantly different from or beyond those prescribed by the bug:
*Consolidated a lot of GrabWindowSnapshot code.
*Moved EnsureRectIsVisibleInRect to views::internal namespace for test access.
*Moved app/win/win_util_unittest.cc to views/window/window_win_unittest.h
*Named ui/base/message_box_win.h instead of ui/base/message_box.h
*Made WindowWin::GetWindowTitleFont static; needed in static contexts.
*Denoted WindowWin::FrameTypeChanged as a Window override, moved code.
*Moved TestGrabWindowSnapshot into new file: chrome/browser/ui/window_snapshot/window_snapshot_mac_unittest.mm
BUG=70141
TEST=none
Review URL: http://codereview.chromium.org/6386009
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@73589 0039d316-1c4b-4281-b951-d872f2087c98
61 files changed, 811 insertions, 770 deletions
diff --git a/app/app.gyp b/app/app.gyp index 6aea564..107d4b30 100644 --- a/app/app.gyp +++ b/app/app.gyp @@ -59,7 +59,6 @@ 'sql/statement_unittest.cc', 'sql/transaction_unittest.cc', 'test_suite.h', - 'win/win_util_unittest.cc', ], 'include_dirs': [ '..', @@ -79,7 +78,6 @@ 'sources!': [ '../ui/base/dragdrop/os_exchange_data_win_unittest.cc', '../ui/base/view_prop_unittest.cc', - 'win_util_unittest.cc', ], }], ['OS =="linux" or OS =="freebsd"', { diff --git a/app/app_base.gypi b/app/app_base.gypi index 944f833..53d67c2 100644 --- a/app/app_base.gypi +++ b/app/app_base.gypi @@ -160,6 +160,8 @@ '../ui/base/l10n/l10n_util_win.cc', '../ui/base/l10n/l10n_util_win.h', '../ui/base/message_box_flags.h', + '../ui/base/message_box_win.cc', + '../ui/base/message_box_win.h', '../ui/base/models/accelerator.h', '../ui/base/models/accelerator_gtk.h', '../ui/base/models/accelerator_cocoa.h', @@ -242,8 +244,6 @@ 'win/scoped_prop.h', 'win/shell.cc', 'win/shell.h', - 'win/win_util.cc', - 'win/win_util.h', '<(gl_binding_output_dir)/gl_bindings_autogen_gl.cc', '<(gl_binding_output_dir)/gl_bindings_autogen_gl.h', '<(gl_binding_output_dir)/gl_bindings_autogen_mock.cc', diff --git a/app/win/win_util.cc b/app/win/win_util.cc deleted file mode 100644 index f372ae5..0000000 --- a/app/win/win_util.cc +++ /dev/null @@ -1,326 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "app/win/win_util.h" - -#include <commdlg.h> -#include <shellapi.h> - -#include <algorithm> - -#include "base/base_switches.h" -#include "base/command_line.h" -#include "base/file_util.h" -#include "base/i18n/rtl.h" -#include "base/logging.h" -#include "base/scoped_handle.h" -#include "base/string_util.h" -#include "base/win/scoped_gdi_object.h" -#include "base/win/scoped_hdc.h" -#include "base/win/win_util.h" -#include "gfx/codec/png_codec.h" -#include "gfx/font.h" -#include "gfx/gdi_util.h" -#include "ui/base/l10n/l10n_util.h" -#include "ui/base/l10n/l10n_util_win.h" - -namespace app { -namespace win { - -const int kAutoHideTaskbarThicknessPx = 2; - -string16 FormatSystemTime(const SYSTEMTIME& time, const string16& format) { - // If the format string is empty, just use the default format. - LPCTSTR format_ptr = NULL; - if (!format.empty()) - format_ptr = format.c_str(); - - int buffer_size = GetTimeFormat(LOCALE_USER_DEFAULT, NULL, &time, format_ptr, - NULL, 0); - - string16 output; - GetTimeFormat(LOCALE_USER_DEFAULT, NULL, &time, format_ptr, - WriteInto(&output, buffer_size), buffer_size); - - return output; -} - -string16 FormatSystemDate(const SYSTEMTIME& date, const string16& format) { - // If the format string is empty, just use the default format. - LPCTSTR format_ptr = NULL; - if (!format.empty()) - format_ptr = format.c_str(); - - int buffer_size = GetDateFormat(LOCALE_USER_DEFAULT, NULL, &date, format_ptr, - NULL, 0); - - string16 output; - GetDateFormat(LOCALE_USER_DEFAULT, NULL, &date, format_ptr, - WriteInto(&output, buffer_size), buffer_size); - - return output; -} - -bool ConvertToLongPath(const string16& short_path, - string16* long_path) { - wchar_t long_path_buf[MAX_PATH]; - DWORD return_value = GetLongPathName(short_path.c_str(), long_path_buf, - MAX_PATH); - if (return_value != 0 && return_value < MAX_PATH) { - *long_path = long_path_buf; - return true; - } - - return false; -} - -bool IsDoubleClick(const POINT& origin, - const POINT& current, - DWORD elapsed_time) { - // The CXDOUBLECLK and CYDOUBLECLK system metrics describe the width and - // height of a rectangle around the origin position, inside of which clicks - // within the double click time are considered double clicks. - return (elapsed_time <= GetDoubleClickTime()) && - (abs(current.x - origin.x) <= (GetSystemMetrics(SM_CXDOUBLECLK) / 2)) && - (abs(current.y - origin.y) <= (GetSystemMetrics(SM_CYDOUBLECLK) / 2)); -} - -bool IsDrag(const POINT& origin, const POINT& current) { - // The CXDRAG and CYDRAG system metrics describe the width and height of a - // rectangle around the origin position, inside of which motion is not - // considered a drag. - return (abs(current.x - origin.x) > (GetSystemMetrics(SM_CXDRAG) / 2)) || - (abs(current.y - origin.y) > (GetSystemMetrics(SM_CYDRAG) / 2)); -} - -bool EdgeHasTopmostAutoHideTaskbar(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) && (monitor != NULL) && - (MonitorFromWindow(taskbar, MONITOR_DEFAULTTONULL) == monitor) && - (GetWindowLong(taskbar, GWL_EXSTYLE) & WS_EX_TOPMOST); -} - -HANDLE GetSectionFromProcess(HANDLE section, HANDLE process, bool read_only) { - HANDLE valid_section = NULL; - DWORD access = STANDARD_RIGHTS_REQUIRED | FILE_MAP_READ; - if (!read_only) - access |= FILE_MAP_WRITE; - DuplicateHandle(process, section, GetCurrentProcess(), &valid_section, access, - FALSE, 0); - return valid_section; -} - -HANDLE GetSectionForProcess(HANDLE section, HANDLE process, bool read_only) { - HANDLE valid_section = NULL; - DWORD access = STANDARD_RIGHTS_REQUIRED | FILE_MAP_READ; - if (!read_only) - access |= FILE_MAP_WRITE; - DuplicateHandle(GetCurrentProcess(), section, process, &valid_section, access, - FALSE, 0); - return valid_section; -} - -void EnsureRectIsVisibleInRect(const gfx::Rect& parent_rect, - gfx::Rect* child_rect, - int padding) { - DCHECK(child_rect); - - // We use padding here because it allows some of the original web page to - // bleed through around the edges. - int twice_padding = padding * 2; - - // FIRST, clamp width and height so we don't open child windows larger than - // the containing parent. - if (child_rect->width() > (parent_rect.width() + twice_padding)) - child_rect->set_width(std::max(0, parent_rect.width() - twice_padding)); - if (child_rect->height() > parent_rect.height() + twice_padding) - child_rect->set_height(std::max(0, parent_rect.height() - twice_padding)); - - // SECOND, clamp x,y position to padding,padding so we don't position child - // windows in hyperspace. - // TODO(mpcomplete): I don't see what the second check in each 'if' does that - // isn't handled by the LAST set of 'ifs'. Maybe we can remove it. - if (child_rect->x() < parent_rect.x() || - child_rect->x() > parent_rect.right()) { - child_rect->set_x(parent_rect.x() + padding); - } - if (child_rect->y() < parent_rect.y() || - child_rect->y() > parent_rect.bottom()) { - child_rect->set_y(parent_rect.y() + padding); - } - - // LAST, nudge the window back up into the client area if its x,y position is - // within the parent bounds but its width/height place it off-screen. - if (child_rect->bottom() > parent_rect.bottom()) - child_rect->set_y(parent_rect.bottom() - child_rect->height() - padding); - if (child_rect->right() > parent_rect.right()) - child_rect->set_x(parent_rect.right() - child_rect->width() - padding); -} - -gfx::Rect GetMonitorBoundsForRect(const gfx::Rect& rect) { - RECT p_rect = rect.ToRECT(); - HMONITOR monitor = MonitorFromRect(&p_rect, MONITOR_DEFAULTTONEAREST); - if (monitor) { - MONITORINFO mi = {0}; - mi.cbSize = sizeof(mi); - GetMonitorInfo(monitor, &mi); - return gfx::Rect(mi.rcWork); - } - NOTREACHED(); - return gfx::Rect(); -} - -bool IsNumPadDigit(int key_code, bool extended_key) { - if (key_code >= VK_NUMPAD0 && key_code <= VK_NUMPAD9) - return true; - - // Check for num pad keys without NumLock. - // Note: there is no easy way to know if a the key that was pressed comes from - // the num pad or the rest of the keyboard. Investigating how - // TranslateMessage() generates the WM_KEYCHAR from an - // ALT + <NumPad sequences> it appears it looks at the extended key flag - // (which is on if the key pressed comes from one of the 3 clusters to - // the left of the numeric keypad). So we use it as well. - return !extended_key && - ((key_code >= VK_PRIOR && key_code <= VK_DOWN) || // All keys but 5 - // and 0. - (key_code == VK_CLEAR) || // Key 5. - (key_code == VK_INSERT)); // Key 0. -} - -void GrabWindowSnapshot(HWND window_handle, - std::vector<unsigned char>* png_representation) { - // Create a memory DC that's compatible with the window. - HDC window_hdc = GetWindowDC(window_handle); - base::win::ScopedHDC mem_hdc(CreateCompatibleDC(window_hdc)); - - // Create a DIB that's the same size as the window. - RECT content_rect = {0, 0, 0, 0}; - ::GetWindowRect(window_handle, &content_rect); - content_rect.right++; // Match what PrintWindow wants. - int width = content_rect.right - content_rect.left; - int height = content_rect.bottom - content_rect.top; - BITMAPINFOHEADER hdr; - gfx::CreateBitmapHeader(width, height, &hdr); - unsigned char *bit_ptr = NULL; - base::win::ScopedBitmap bitmap( - CreateDIBSection(mem_hdc, - reinterpret_cast<BITMAPINFO*>(&hdr), - DIB_RGB_COLORS, - reinterpret_cast<void **>(&bit_ptr), - NULL, 0)); - - SelectObject(mem_hdc, bitmap); - // Clear the bitmap to white (so that rounded corners on windows - // show up on a white background, and strangely-shaped windows - // look reasonable). Not capturing an alpha mask saves a - // bit of space. - PatBlt(mem_hdc, 0, 0, width, height, WHITENESS); - // Grab a copy of the window - // First, see if PrintWindow is defined (it's not in Windows 2000). - typedef BOOL (WINAPI *PrintWindowPointer)(HWND, HDC, UINT); - PrintWindowPointer print_window = - reinterpret_cast<PrintWindowPointer>( - GetProcAddress(GetModuleHandle(L"User32.dll"), "PrintWindow")); - - // If PrintWindow is defined, use it. It will work on partially - // obscured windows, and works better for out of process sub-windows. - // Otherwise grab the bits we can get with BitBlt; it's better - // than nothing and will work fine in the average case (window is - // completely on screen). - if (print_window) - (*print_window)(window_handle, mem_hdc, 0); - else - BitBlt(mem_hdc, 0, 0, width, height, window_hdc, 0, 0, SRCCOPY); - - // We now have a copy of the window contents in a DIB, so - // encode it into a useful format for posting to the bug report - // server. - gfx::PNGCodec::Encode(bit_ptr, gfx::PNGCodec::FORMAT_BGRA, - width, height, width * 4, true, - png_representation); - - ReleaseDC(window_handle, window_hdc); -} - -bool IsWindowActive(HWND hwnd) { - WINDOWINFO info; - return ::GetWindowInfo(hwnd, &info) && - ((info.dwWindowStatus & WS_ACTIVECAPTION) != 0); -} - -bool IsReservedName(const string16& filename) { - // This list is taken from the MSDN article "Naming a file" - // http://msdn2.microsoft.com/en-us/library/aa365247(VS.85).aspx - // I also added clock$ because GetSaveFileName seems to consider it as a - // reserved name too. - static const wchar_t* const known_devices[] = { - L"con", L"prn", L"aux", L"nul", L"com1", L"com2", L"com3", L"com4", L"com5", - L"com6", L"com7", L"com8", L"com9", L"lpt1", L"lpt2", L"lpt3", L"lpt4", - L"lpt5", L"lpt6", L"lpt7", L"lpt8", L"lpt9", L"clock$" - }; - string16 filename_lower = StringToLowerASCII(filename); - - for (int i = 0; i < arraysize(known_devices); ++i) { - // Exact match. - if (filename_lower == known_devices[i]) - return true; - // Starts with "DEVICE.". - if (filename_lower.find(string16(known_devices[i]) + L".") == 0) - return true; - } - - static const wchar_t* const magic_names[] = { - // These file names are used by the "Customize folder" feature of the shell. - L"desktop.ini", - L"thumbs.db", - }; - - for (int i = 0; i < arraysize(magic_names); ++i) { - if (filename_lower == magic_names[i]) - return true; - } - - return false; -} - -// In addition to passing the RTL flags to ::MessageBox if we are running in an -// RTL locale, we need to make sure that LTR strings are rendered correctly by -// adding the appropriate Unicode directionality marks. -int MessageBox(HWND hwnd, - const string16& text, - const string16& caption, - UINT flags) { - if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kNoMessageBox)) - return IDOK; - - UINT actual_flags = flags; - if (base::i18n::IsRTL()) - actual_flags |= MB_RIGHT | MB_RTLREADING; - - string16 localized_text = text; - base::i18n::AdjustStringForLocaleDirection(&localized_text); - const wchar_t* text_ptr = localized_text.c_str(); - - string16 localized_caption = caption; - base::i18n::AdjustStringForLocaleDirection(&localized_caption); - const wchar_t* caption_ptr = localized_caption.c_str(); - - return ::MessageBox(hwnd, text_ptr, caption_ptr, actual_flags); -} - -gfx::Font GetWindowTitleFont() { - NONCLIENTMETRICS ncm; - base::win::GetNonClientMetrics(&ncm); - l10n_util::AdjustUIFont(&(ncm.lfCaptionFont)); - base::win::ScopedHFONT caption_font(CreateFontIndirect(&(ncm.lfCaptionFont))); - return gfx::Font(caption_font); -} - -} // namespace win -} // namespace app diff --git a/app/win/win_util.h b/app/win/win_util.h deleted file mode 100644 index 71b0f78..0000000 --- a/app/win/win_util.h +++ /dev/null @@ -1,114 +0,0 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef APP_WIN_WIN_UTIL_H_ -#define APP_WIN_WIN_UTIL_H_ -#pragma once - -#include <windows.h> - -#include <vector> - -#include "base/string16.h" - -class FilePath; - -namespace gfx { -class Font; -class Rect; -} - -namespace app { -namespace win { - -// Creates a string interpretation of the time of day represented by the given -// SYSTEMTIME that's appropriate for the user's default locale. -// Format can be an empty string (for the default format), or a "format picture" -// as specified in the Windows documentation for GetTimeFormat(). -string16 FormatSystemTime(const SYSTEMTIME& time, - const string16& format); - -// Creates a string interpretation of the date represented by the given -// SYSTEMTIME that's appropriate for the user's default locale. -// Format can be an empty string (for the default format), or a "format picture" -// as specified in the Windows documentation for GetDateFormat(). -string16 FormatSystemDate(const SYSTEMTIME& date, - const string16& format); - -// Returns the long path name given a short path name. A short path name -// is a path that follows the 8.3 convention and has ~x in it. If the -// path is already a long path name, the function returns the current -// path without modification. -bool ConvertToLongPath(const string16& short_path, string16* long_path); - -// Returns true if the current point is close enough to the origin point in -// space and time that it would be considered a double click. -bool IsDoubleClick(const POINT& origin, - const POINT& current, - DWORD elapsed_time); - -// Returns true if the current point is far enough from the origin that it -// would be considered a drag. -bool IsDrag(const POINT& origin, const POINT& current); - -// Returns true if edge |edge| (one of ABE_LEFT, TOP, RIGHT, or BOTTOM) of -// monitor |monitor| has an auto-hiding taskbar that's always-on-top. -bool EdgeHasTopmostAutoHideTaskbar(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); - -// Duplicates a section handle from the current process for use in another -// process. Returns the new valid handle or NULL on failure. -HANDLE GetSectionForProcess(HANDLE section, HANDLE process, bool read_only); - -// Adjusts the value of |child_rect| if necessary to ensure that it is -// completely visible within |parent_rect|. -void EnsureRectIsVisibleInRect(const gfx::Rect& parent_rect, - gfx::Rect* child_rect, - int padding); - -// Returns the bounds for the monitor that contains the largest area of -// intersection with the specified rectangle. -gfx::Rect GetMonitorBoundsForRect(const gfx::Rect& rect); - -// Returns true if the virtual key code is a digit coming from the numeric -// keypad (with or without NumLock on). |extended_key| should be set to the -// extended key flag specified in the WM_KEYDOWN/UP where the |key_code| -// originated. -bool IsNumPadDigit(int key_code, bool extended_key); - -// Grabs a snapshot of the designated window and stores a PNG representation -// into a byte vector. -void GrabWindowSnapshot(HWND window_handle, - std::vector<unsigned char>* png_representation); - -// Returns whether the specified window is the current active window. -bool IsWindowActive(HWND hwnd); - -// Returns whether the specified file name is a reserved name on windows. -// This includes names like "com2.zip" (which correspond to devices) and -// desktop.ini and thumbs.db which have special meaning to the windows shell. -bool IsReservedName(const string16& filename); - -// A wrapper around Windows' MessageBox function. Using a Chrome specific -// MessageBox function allows us to control certain RTL locale flags so that -// callers don't have to worry about adding these flags when running in a -// right-to-left locale. -int MessageBox(HWND hwnd, - const string16& text, - const string16& caption, - UINT flags); - -// Returns the system set window title font. -gfx::Font GetWindowTitleFont(); - -// The thickness of an auto-hide taskbar in pixels. -extern const int kAutoHideTaskbarThicknessPx; - -} // namespace win -} // namespace app - -#endif // APP_WIN_WIN_UTIL_H_ diff --git a/base/base_switches.cc b/base/base_switches.cc index a1d688a..78f55a7 100644 --- a/base/base_switches.cc +++ b/base/base_switches.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -24,8 +24,8 @@ const char kFullMemoryCrashReport[] = "full-memory-crash-report"; // Suppresses all error dialogs when present. const char kNoErrorDialogs[] = "noerrdialogs"; -// Disable app::win::MessageBox. This is useful when running as part of -// scripts that do not have a user interface. +// Disable ui::MessageBox. This is useful when running as part of scripts that +// do not have a user interface. const char kNoMessageBox[] = "no-message-box"; // When running certain tests that spawn child processes, this switch indicates diff --git a/base/mac/mac_util.h b/base/mac/mac_util.h index 968756a..d75fb6e 100644 --- a/base/mac/mac_util.h +++ b/base/mac/mac_util.h @@ -8,7 +8,6 @@ #include <Carbon/Carbon.h> #include <string> -#include <vector> #include "base/logging.h" @@ -17,10 +16,8 @@ #if defined(__OBJC__) #import <Foundation/Foundation.h> -@class NSWindow; #else // __OBJC__ class NSImage; -class NSWindow; #endif // __OBJC__ class FilePath; @@ -77,11 +74,6 @@ void SetCursorVisibility(bool visible); // Should windows miniaturize on a double-click (on the title bar)? bool ShouldWindowsMiniaturizeOnDoubleClick(); -// Pulls a snapshot of the entire browser into png_representation. -void GrabWindowSnapshot(NSWindow* window, - std::vector<unsigned char>* png_representation, - int* width, int* height); - // Activates the process with the given PID. void ActivateProcess(pid_t pid); diff --git a/base/mac/mac_util.mm b/base/mac/mac_util.mm index c32be37..7f3be18 100644 --- a/base/mac/mac_util.mm +++ b/base/mac/mac_util.mm @@ -9,7 +9,6 @@ #include "base/file_path.h" #include "base/logging.h" #include "base/mac/scoped_cftyperef.h" -#include "base/message_loop.h" #include "base/scoped_nsobject.h" #include "base/sys_string_conversions.h" @@ -229,36 +228,6 @@ bool ShouldWindowsMiniaturizeOnDoubleClick() { [NSWindow performSelector:@selector(_shouldMiniaturizeOnDoubleClick)]; } -void GrabWindowSnapshot(NSWindow* window, - std::vector<unsigned char>* png_representation, - int* width, int* height) { - png_representation->clear(); - *width = 0; - *height = 0; - - // Make sure to grab the "window frame" view so we get current tab + - // tabstrip. - NSView* view = [[window contentView] superview]; - ScopedCFTypeRef<CGImageRef> windowSnapshot(CGWindowListCreateImage( - CGRectNull, kCGWindowListOptionIncludingWindow, - [[view window] windowNumber], kCGWindowImageBoundsIgnoreFraming)); - if (CGImageGetWidth(windowSnapshot) <= 0) - return; - - scoped_nsobject<NSBitmapImageRep> rep( - [[NSBitmapImageRep alloc] initWithCGImage:windowSnapshot]); - NSData* data = [rep representationUsingType:NSPNGFileType properties:nil]; - const unsigned char* buf = static_cast<const unsigned char*>([data bytes]); - NSUInteger length = [data length]; - if (buf == NULL || length == 0) - return; - - *width = static_cast<int>([rep pixelsWide]); - *height = static_cast<int>([rep pixelsHigh]); - png_representation->assign(buf, buf + length); - DCHECK(png_representation->size() > 0); -} - void ActivateProcess(pid_t pid) { ProcessSerialNumber process; OSStatus status = GetProcessForPID(pid, &process); diff --git a/base/mac/mac_util_unittest.mm b/base/mac/mac_util_unittest.mm index 17fc04f..bae0019 100644 --- a/base/mac/mac_util_unittest.mm +++ b/base/mac/mac_util_unittest.mm @@ -3,7 +3,6 @@ // found in the LICENSE file. #import <Cocoa/Cocoa.h> -#include <vector> #include "base/mac/mac_util.h" @@ -11,7 +10,6 @@ #include "base/file_util.h" #include "base/mac/scoped_cftyperef.h" #include "base/scoped_nsobject.h" -#include "base/scoped_ptr.h" #include "testing/gtest/include/gtest/gtest.h" #include "testing/platform_test.h" @@ -52,36 +50,6 @@ TEST_F(MacUtilTest, TestLibraryPath) { EXPECT_FALSE(library_dir.value().empty()); } -TEST_F(MacUtilTest, TestGrabWindowSnapshot) { - // Launch a test window so we can take a snapshot. - NSRect frame = NSMakeRect(0, 0, 400, 400); - scoped_nsobject<NSWindow> window( - [[NSWindow alloc] initWithContentRect:frame - styleMask:NSBorderlessWindowMask - backing:NSBackingStoreBuffered - defer:NO]); - [window setBackgroundColor:[NSColor whiteColor]]; - [window makeKeyAndOrderFront:NSApp]; - - scoped_ptr<std::vector<unsigned char> > png_representation( - new std::vector<unsigned char>); - int width, height; - GrabWindowSnapshot(window, png_representation.get(), - &width, &height); - - // Copy png back into NSData object so we can make sure we grabbed a png. - scoped_nsobject<NSData> image_data( - [[NSData alloc] initWithBytes:&(*png_representation)[0] - length:png_representation->size()]); - NSBitmapImageRep* rep = [NSBitmapImageRep imageRepWithData:image_data.get()]; - EXPECT_TRUE([rep isKindOfClass:[NSBitmapImageRep class]]); - EXPECT_TRUE(CGImageGetWidth([rep CGImage]) == 400); - NSColor* color = [rep colorAtX:200 y:200]; - CGFloat red = 0, green = 0, blue = 0, alpha = 0; - [color getRed:&red green:&green blue:&blue alpha:&alpha]; - EXPECT_GE(red + green + blue, 3.0); -} - TEST_F(MacUtilTest, TestGetAppBundlePath) { FilePath out; diff --git a/chrome/browser/autocomplete/autocomplete_edit_view_win.cc b/chrome/browser/autocomplete/autocomplete_edit_view_win.cc index cca0d08..24a1be0 100644 --- a/chrome/browser/autocomplete/autocomplete_edit_view_win.cc +++ b/chrome/browser/autocomplete/autocomplete_edit_view_win.cc @@ -12,7 +12,6 @@ #include <textserv.h> #include "app/win/iat_patch_function.h" -#include "app/win/win_util.h" #include "base/auto_reset.h" #include "base/basictypes.h" #include "base/i18n/rtl.h" @@ -50,6 +49,7 @@ #include "ui/base/keycodes/keyboard_codes.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/l10n/l10n_util_win.h" +#include "views/controls/textfield/native_textfield_win.h" #include "views/drag_utils.h" #include "views/focus/focus_util_win.h" #include "views/widget/widget.h" @@ -261,6 +261,16 @@ struct AutocompleteEditState { const AutocompleteEditViewWin::State view_state; }; +// Returns true if the current point is far enough from the origin that it +// would be considered a drag. +bool IsDrag(const POINT& origin, const POINT& current) { + // The CXDRAG and CYDRAG system metrics describe the width and height of a + // rectangle around the origin position, inside of which motion is not + // considered a drag. + return (abs(current.x - origin.x) > (GetSystemMetrics(SM_CXDRAG) / 2)) || + (abs(current.y - origin.y) > (GetSystemMetrics(SM_CYDRAG) / 2)); +} + } // namespace /////////////////////////////////////////////////////////////////////////////// @@ -963,7 +973,7 @@ bool AutocompleteEditViewWin::SkipDefaultKeyEventProcessing( // We don't process ALT + numpad digit as accelerators, they are used for // entering special characters. We do translate alt-home. if (e.IsAltDown() && (key != ui::VKEY_HOME) && - app::win::IsNumPadDigit(key, e.IsExtendedKey())) + views::NativeTextfieldWin::IsNumPadDigit(key, e.IsExtendedKey())) return true; // Skip accelerators for key combinations omnibox wants to crack. This list @@ -1459,8 +1469,8 @@ void AutocompleteEditViewWin::OnLButtonDown(UINT keys, const CPoint& point) { // double_click_time_ from the current message's time even if the timer has // wrapped in between. const bool is_triple_click = tracking_double_click_ && - app::win::IsDoubleClick(double_click_point_, point, - GetCurrentMessage()->time - double_click_time_); + views::NativeTextfieldWin::IsDoubleClick(double_click_point_, point, + GetCurrentMessage()->time - double_click_time_); tracking_double_click_ = false; if (!gaining_focus_.get() && !is_triple_click) @@ -1559,7 +1569,7 @@ void AutocompleteEditViewWin::OnMouseMove(UINT keys, const CPoint& point) { return; } - if (tracking_click_[kLeft] && !app::win::IsDrag(click_point_[kLeft], point)) + if (tracking_click_[kLeft] && !IsDrag(click_point_[kLeft], point)) return; tracking_click_[kLeft] = false; @@ -2380,7 +2390,7 @@ ITextDocument* AutocompleteEditViewWin::GetTextObjectModel() const { } void AutocompleteEditViewWin::StartDragIfNecessary(const CPoint& point) { - if (initiated_drag_ || !app::win::IsDrag(click_point_[kLeft], point)) + if (initiated_drag_ || !IsDrag(click_point_[kLeft], point)) return; ui::OSExchangeData data; @@ -2537,7 +2547,7 @@ void AutocompleteEditViewWin::SelectAllIfNecessary(MouseButton button, const CPoint& point) { // When the user has clicked and released to give us focus, select all. if (tracking_click_[button] && - !app::win::IsDrag(click_point_[button], point)) { + !IsDrag(click_point_[button], point)) { // Select all in the reverse direction so as not to scroll the caret // into view and shift the contents jarringly. SelectAll(true); diff --git a/chrome/browser/browser_main_win.cc b/chrome/browser/browser_main_win.cc index 56b20a4..6616894 100644 --- a/chrome/browser/browser_main_win.cc +++ b/chrome/browser/browser_main_win.cc @@ -10,7 +10,6 @@ #include <algorithm> -#include "app/win/win_util.h" #include "base/command_line.h" #include "base/environment.h" #include "base/i18n/rtl.h" @@ -37,6 +36,7 @@ #include "net/socket/ssl_client_socket_nss_factory.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/l10n/l10n_util_win.h" +#include "ui/base/message_box_win.h" #include "views/focus/accelerator_handler.h" #include "views/window/window.h" @@ -57,8 +57,7 @@ void WarnAboutMinimumSystemRequirements() { const string16 text = l10n_util::GetStringUTF16(IDS_UNSUPPORTED_OS_PRE_WIN_XP); const string16 caption = l10n_util::GetStringUTF16(IDS_PRODUCT_NAME); - app::win::MessageBox(NULL, text, caption, - MB_OK | MB_ICONWARNING | MB_TOPMOST); + ui::MessageBox(NULL, text, caption, MB_OK | MB_ICONWARNING | MB_TOPMOST); } } @@ -75,7 +74,7 @@ void ShowCloseBrowserFirstMessageBox() { const string16 text = l10n_util::GetStringUTF16(IDS_UNINSTALL_CLOSE_APP); const string16 caption = l10n_util::GetStringUTF16(IDS_PRODUCT_NAME); const UINT flags = MB_OK | MB_ICONWARNING | MB_TOPMOST; - app::win::MessageBox(NULL, text, caption, flags); + ui::MessageBox(NULL, text, caption, flags); } int DoUninstallTasks(bool chrome_still_running) { @@ -167,7 +166,7 @@ int HandleIconsCommands(const CommandLine &parsed_command_line) { l10n_util::GetStringFUTF16(IDS_HIDE_ICONS_NOT_SUPPORTED, cp_applet); const string16 caption = l10n_util::GetStringUTF16(IDS_PRODUCT_NAME); const UINT flags = MB_OKCANCEL | MB_ICONWARNING | MB_TOPMOST; - if (IDOK == app::win::MessageBox(NULL, msg, caption, flags)) + if (IDOK == ui::MessageBox(NULL, msg, caption, flags)) ShellExecute(NULL, NULL, L"appwiz.cpl", NULL, NULL, SW_SHOWNORMAL); return ResultCodes::NORMAL_EXIT; // Exit as we are not launching browser. } @@ -194,7 +193,7 @@ bool CheckMachineLevelInstall() { l10n_util::GetStringUTF16(IDS_MACHINE_LEVEL_INSTALL_CONFLICT); const string16 caption = l10n_util::GetStringUTF16(IDS_PRODUCT_NAME); const UINT flags = MB_OK | MB_ICONERROR | MB_TOPMOST; - app::win::MessageBox(NULL, text, caption, flags); + ui::MessageBox(NULL, text, caption, flags); FilePath uninstall_path(InstallUtil::GetChromeUninstallCmd(false, dist)); CommandLine uninstall_cmd(uninstall_path); if (!uninstall_cmd.GetProgram().value().empty()) { diff --git a/chrome/browser/dom_ui/bug_report_ui.cc b/chrome/browser/dom_ui/bug_report_ui.cc index ffbf29e..c69a2e2 100644 --- a/chrome/browser/dom_ui/bug_report_ui.cc +++ b/chrome/browser/dom_ui/bug_report_ui.cc @@ -25,6 +25,7 @@ #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_list.h" #include "chrome/browser/ui/browser_window.h" +#include "chrome/browser/ui/window_snapshot/window_snapshot.h" #include "chrome/common/chrome_paths.h" #include "chrome/common/jstemplate_builder.h" #include "chrome/common/url_constants.h" @@ -36,18 +37,6 @@ #include "ui/base/l10n/l10n_util.h" #include "ui/base/resource/resource_bundle.h" -#if defined(USE_X11) -#include "ui/base/x/x11_util.h" -#elif defined(OS_MACOSX) -#include "base/mac/mac_util.h" -#elif defined(OS_WIN) -#include "app/win/win_util.h" -#endif - -#if defined(TOOLKIT_VIEWS) -#include "views/window/window.h" -#endif - #if defined(OS_CHROMEOS) #include "base/file_util.h" #include "base/path_service.h" @@ -148,7 +137,8 @@ void RefreshLastScreenshot(Browser* browser) { else last_screenshot_png = new std::vector<unsigned char>; - screen_size = browser->window()->GrabWindowSnapshot(last_screenshot_png); + gfx::NativeWindow native_window = browser->window()->GetNativeHandle(); + screen_size = browser::GrabWindowSnapshot(native_window, last_screenshot_png); } void ShowHtmlBugReportView(Browser* browser) { diff --git a/chrome/browser/download/base_file.cc b/chrome/browser/download/base_file.cc index ad01086..79f38e9 100644 --- a/chrome/browser/download/base_file.cc +++ b/chrome/browser/download/base_file.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -14,7 +14,6 @@ #include "chrome/browser/download/download_util.h" #if defined(OS_WIN) -#include "app/win/win_util.h" #include "chrome/common/win_safe_util.h" #elif defined(OS_MACOSX) #include "chrome/browser/ui/cocoa/file_metadata.h" diff --git a/chrome/browser/download/download_util.cc b/chrome/browser/download/download_util.cc index f7bf52f..cbc352b 100644 --- a/chrome/browser/download/download_util.cc +++ b/chrome/browser/download/download_util.cc @@ -69,7 +69,6 @@ #endif // defined(TOOLKIT_USES_GTK) #if defined(OS_WIN) -#include "app/win/win_util.h" #include "base/win/scoped_comptr.h" #include "chrome/browser/browser_list.h" #include "chrome/browser/ui/views/frame/browser_view.h" @@ -119,6 +118,44 @@ bool IsShellIntegratedExtension(const string16& extension) { return false; } + +// Returns whether the specified file name is a reserved name on windows. +// This includes names like "com2.zip" (which correspond to devices) and +// desktop.ini and thumbs.db which have special meaning to the windows shell. +bool IsReservedName(const string16& filename) { + // This list is taken from the MSDN article "Naming a file" + // http://msdn2.microsoft.com/en-us/library/aa365247(VS.85).aspx + // I also added clock$ because GetSaveFileName seems to consider it as a + // reserved name too. + static const wchar_t* const known_devices[] = { + L"con", L"prn", L"aux", L"nul", L"com1", L"com2", L"com3", L"com4", L"com5", + L"com6", L"com7", L"com8", L"com9", L"lpt1", L"lpt2", L"lpt3", L"lpt4", + L"lpt5", L"lpt6", L"lpt7", L"lpt8", L"lpt9", L"clock$" + }; + string16 filename_lower = StringToLowerASCII(filename); + + for (int i = 0; i < arraysize(known_devices); ++i) { + // Exact match. + if (filename_lower == known_devices[i]) + return true; + // Starts with "DEVICE.". + if (filename_lower.find(string16(known_devices[i]) + L".") == 0) + return true; + } + + static const wchar_t* const magic_names[] = { + // These file names are used by the "Customize folder" feature of the shell. + L"desktop.ini", + L"thumbs.db", + }; + + for (int i = 0; i < arraysize(magic_names); ++i) { + if (filename_lower == magic_names[i]) + return true; + } + + return false; +} #endif // OS_WIN } // namespace @@ -251,7 +288,7 @@ void GenerateSafeFileName(const std::string& mime_type, FilePath* file_name) { // Prepend "_" to the file name if it's a reserved name FilePath::StringType leaf_name = file_name->BaseName().value(); DCHECK(!leaf_name.empty()); - if (app::win::IsReservedName(leaf_name)) { + if (IsReservedName(leaf_name)) { leaf_name = FilePath::StringType(FILE_PATH_LITERAL("_")) + leaf_name; *file_name = file_name->DirName(); if (file_name->value() == FilePath::kCurrentDirectory) { diff --git a/chrome/browser/enumerate_modules_model_win.cc b/chrome/browser/enumerate_modules_model_win.cc index acfed88..bd2cc51 100644 --- a/chrome/browser/enumerate_modules_model_win.cc +++ b/chrome/browser/enumerate_modules_model_win.cc @@ -7,7 +7,6 @@ #include <Tlhelp32.h> #include <wintrust.h> -#include "app/win/win_util.h" #include "base/command_line.h" #include "base/environment.h" #include "base/file_path.h" @@ -75,8 +74,23 @@ struct FindModule { const ModuleEnumerator::Module& module; }; +// Returns the long path name given a short path name. A short path name is a +// path that follows the 8.3 convention and has ~x in it. If the path is already +// a long path name, the function returns the current path without modification. +bool ConvertToLongPath(const string16& short_path, string16* long_path) { + wchar_t long_path_buf[MAX_PATH]; + DWORD return_value = GetLongPathName(short_path.c_str(), long_path_buf, + MAX_PATH); + if (return_value != 0 && return_value < MAX_PATH) { + *long_path = long_path_buf; + return true; + } + + return false; } +} // namespace + // The browser process module blacklist. This lists modules that are known // to cause compatibility issues within the browser process. When adding to this // list, make sure that all paths are lower-case, in long pathname form, end @@ -220,7 +234,7 @@ static void GenerateHash(const std::string& input, std::string* output) { // static void ModuleEnumerator::NormalizeModule(Module* module) { string16 path = module->location; - if (!app::win::ConvertToLongPath(path, &module->location)) + if (!ConvertToLongPath(path, &module->location)) module->location = path; module->location = l10n_util::ToLower(module->location); diff --git a/chrome/browser/extensions/extensions_startup.cc b/chrome/browser/extensions/extensions_startup.cc index b44aade..cd395cf 100644 --- a/chrome/browser/extensions/extensions_startup.cc +++ b/chrome/browser/extensions/extensions_startup.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -12,7 +12,7 @@ #include "chrome/common/chrome_switches.h" #if defined(OS_WIN) -#include "app/win/win_util.h" +#include "ui/base/message_box_win.h" #endif ExtensionsStartupUtil::ExtensionsStartupUtil() : pack_job_succeeded_(false) {} @@ -36,7 +36,7 @@ void ExtensionsStartupUtil::ShowPackExtensionMessage( const std::wstring& caption, const std::wstring& message) { #if defined(OS_WIN) - app::win::MessageBox(NULL, message, caption, MB_OK | MB_SETFOREGROUND); + ui::MessageBox(NULL, message, caption, MB_OK | MB_SETFOREGROUND); #else // Just send caption & text to stdout on mac & linux. std::string out_text = WideToASCII(caption); diff --git a/chrome/browser/importer/importer.cc b/chrome/browser/importer/importer.cc index b41efef..4651040 100644 --- a/chrome/browser/importer/importer.cc +++ b/chrome/browser/importer/importer.cc @@ -30,8 +30,8 @@ // TODO(port): Port these files. #if defined(OS_WIN) -#include "app/win/win_util.h" #include "chrome/browser/ui/views/importer_lock_view.h" +#include "ui/base/message_box_win.h" #include "views/window/window.h" #elif defined(OS_MACOSX) #include "chrome/browser/ui/cocoa/importer/importer_lock_dialog.h" @@ -197,7 +197,7 @@ void ImporterHost::StartImportSettings( // credentials. if (profile_info.browser_type == importer::GOOGLE_TOOLBAR5) { if (!toolbar_importer_utils::IsGoogleGAIACookieInstalled()) { - app::win::MessageBox( + ui::MessageBox( NULL, UTF16ToWide(l10n_util::GetStringUTF16( IDS_IMPORTER_GOOGLE_LOGIN_TEXT)).c_str(), diff --git a/chrome/browser/platform_util_win.cc b/chrome/browser/platform_util_win.cc index f03f653..ecd5130 100644 --- a/chrome/browser/platform_util_win.cc +++ b/chrome/browser/platform_util_win.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -11,7 +11,6 @@ #include "app/win/scoped_co_mem.h" #include "app/win/shell.h" -#include "app/win/win_util.h" #include "base/file_path.h" #include "base/file_util.h" #include "base/path_service.h" @@ -25,6 +24,7 @@ #include "chrome/installer/util/install_util.h" #include "gfx/native_widget_types.h" #include "googleurl/src/gurl.h" +#include "ui/base/message_box_win.h" namespace platform_util { @@ -162,13 +162,13 @@ bool IsVisible(gfx::NativeView view) { void SimpleErrorBox(gfx::NativeWindow parent, const string16& title, const string16& message) { - app::win::MessageBox(parent, message, title, MB_OK | MB_SETFOREGROUND); + ui::MessageBox(parent, message, title, MB_OK | MB_SETFOREGROUND); } bool SimpleYesNoBox(gfx::NativeWindow parent, const string16& title, const string16& message) { - return app::win::MessageBox(parent, message.c_str(), title.c_str(), + return ui::MessageBox(parent, message.c_str(), title.c_str(), MB_YESNO | MB_ICONWARNING | MB_SETFOREGROUND) == IDYES; } diff --git a/chrome/browser/renderer_host/browser_render_process_host.cc b/chrome/browser/renderer_host/browser_render_process_host.cc index 5d488cf..89cf36f 100644 --- a/chrome/browser/renderer_host/browser_render_process_host.cc +++ b/chrome/browser/renderer_host/browser_render_process_host.cc @@ -100,7 +100,7 @@ #if defined(OS_WIN) #include <objbase.h> -#include "app/win/win_util.h" +#include "chrome/common/section_util_win.h" #endif using WebKit::WebCache; @@ -888,7 +888,7 @@ TransportDIB* BrowserRenderProcessHost::MapTransportDIB( TransportDIB::Id dib_id) { #if defined(OS_WIN) // On Windows we need to duplicate the handle from the remote process - HANDLE section = app::win::GetSectionFromProcess( + HANDLE section = chrome::GetSectionFromProcess( dib_id.handle, GetHandle(), false /* read write */); return TransportDIB::Map(section); #elif defined(OS_MACOSX) diff --git a/chrome/browser/tab_contents/thumbnail_generator.cc b/chrome/browser/tab_contents/thumbnail_generator.cc index d30cb4e..3a06bdd 100644 --- a/chrome/browser/tab_contents/thumbnail_generator.cc +++ b/chrome/browser/tab_contents/thumbnail_generator.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -31,7 +31,7 @@ #include "third_party/skia/include/core/SkBitmap.h" #if defined(OS_WIN) -#include "app/win/win_util.h" +#include "chrome/common/section_util_win.h" #endif // Overview @@ -268,7 +268,7 @@ void ThumbnailGenerator::AskForSnapshot(RenderWidgetHost* renderer, // Duplicate the handle to the DIB here because the renderer process does not // have permission. The duplicated handle is owned by the renderer process, // which is responsible for closing it. - TransportDIB::Handle renderer_dib_handle = app::win::GetSectionForProcess( + TransportDIB::Handle renderer_dib_handle = chrome::GetSectionForProcess( thumbnail_dib->handle(), renderer->process()->GetHandle(), false); diff --git a/chrome/browser/ui/browser_window.h b/chrome/browser/ui/browser_window.h index 5251502..f7832f3 100644 --- a/chrome/browser/ui/browser_window.h +++ b/chrome/browser/ui/browser_window.h @@ -6,8 +6,6 @@ #define CHROME_BROWSER_UI_BROWSER_WINDOW_H_ #pragma once -#include <vector> - #include "chrome/browser/tab_contents/navigation_entry.h" #include "chrome/common/content_settings_types.h" #include "gfx/native_widget_types.h" @@ -344,10 +342,6 @@ class BrowserWindow { // Construct a FindBar implementation for the specified |browser|. static FindBar* CreateFindBar(Browser* browser_window); - // Grabs a snapshot of the current browser window and returns the bounds. - virtual gfx::Rect GrabWindowSnapshot(std::vector<unsigned char>* - png_representation) = 0; - protected: friend class BrowserList; friend class BrowserView; diff --git a/chrome/browser/ui/cocoa/browser_window_cocoa.h b/chrome/browser/ui/cocoa/browser_window_cocoa.h index 398ba0e..15eebf9 100644 --- a/chrome/browser/ui/cocoa/browser_window_cocoa.h +++ b/chrome/browser/ui/cocoa/browser_window_cocoa.h @@ -113,9 +113,6 @@ class BrowserWindowCocoa : public BrowserWindow, virtual void HideInstant(bool instant_is_active); virtual gfx::Rect GetInstantBounds(); - virtual gfx::Rect GrabWindowSnapshot(std::vector<unsigned char>* - png_representation); - // Overridden from NotificationObserver virtual void Observe(NotificationType type, const NotificationSource& source, diff --git a/chrome/browser/ui/cocoa/browser_window_cocoa.mm b/chrome/browser/ui/cocoa/browser_window_cocoa.mm index 362e852..e5f813eb 100644 --- a/chrome/browser/ui/cocoa/browser_window_cocoa.mm +++ b/chrome/browser/ui/cocoa/browser_window_cocoa.mm @@ -7,7 +7,6 @@ #include "base/command_line.h" #include "base/logging.h" #include "base/message_loop.h" -#include "base/mac/mac_util.h" #include "base/sys_string_conversions.h" #include "chrome/app/chrome_command_ids.h" #include "chrome/browser/bookmarks/bookmark_utils.h" @@ -600,13 +599,6 @@ gfx::Rect BrowserWindowCocoa::GetInstantBounds() { return bounds; } -gfx::Rect BrowserWindowCocoa::GrabWindowSnapshot(std::vector<unsigned char>* - png_representation) { - int width = 0, height = 0; - base::mac::GrabWindowSnapshot(window(), png_representation, &width, &height); - return gfx::Rect(width, height); -} - void BrowserWindowCocoa::Observe(NotificationType type, const NotificationSource& source, const NotificationDetails& details) { diff --git a/chrome/browser/ui/cocoa/bug_report_window_controller.mm b/chrome/browser/ui/cocoa/bug_report_window_controller.mm index c55954c..b323379 100644 --- a/chrome/browser/ui/cocoa/bug_report_window_controller.mm +++ b/chrome/browser/ui/cocoa/bug_report_window_controller.mm @@ -1,4 +1,4 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -9,6 +9,7 @@ #include "chrome/browser/bug_report_util.h" #include "chrome/browser/tab_contents/tab_contents.h" #include "chrome/browser/tab_contents/tab_contents_view.h" +#include "chrome/browser/ui/window_snapshot/window_snapshot.h" #include "grit/chromium_strings.h" #include "grit/generated_resources.h" #include "third_party/GTM/AppKit/GTMUILocalizerAndLayoutTweaker.h" @@ -41,6 +42,9 @@ l10n_util::GetNSStringWithFixup(IDS_BUGREPORT_OTHER_PROBLEM), nil]; + pngHeight_ = 0; + pngWidth_ = 0; + if (currentTab_ != NULL) { // Get data from current tab, if one exists. This dialog could be called // from the main menu with no tab contents, so currentTab_ is not @@ -62,18 +66,16 @@ [self setPageURL:base::SysUTF8ToNSString( currentTab_->controller().GetActiveEntry()->url().spec())]; [self setPageTitle:base::SysUTF16ToNSString(currentTab_->GetTitle())]; - base::mac::GrabWindowSnapshot( - currentTab_->view()->GetTopLevelNativeWindow(), &pngData_, - &pngWidth_, &pngHeight_); + gfx::Rect pngRect = browser::GrabWindowSnapshot( + currentTab_->view()->GetTopLevelNativeWindow(), &pngData_); + pngWidth_ = pngRect.width(); + pngHeight_ = pngRect.height(); } else { // If no current tab exists, create a menu without the "broken page" // options, with page URL and title empty, and screenshot disabled. [self setSendScreenshot:NO]; [self setDisableScreenshotCheckbox:YES]; } - - pngHeight_ = 0; - pngWidth_ = 0; } return self; } diff --git a/chrome/browser/ui/gtk/browser_window_gtk.cc b/chrome/browser/ui/gtk/browser_window_gtk.cc index 1a49281..12458d3 100644 --- a/chrome/browser/ui/gtk/browser_window_gtk.cc +++ b/chrome/browser/ui/gtk/browser_window_gtk.cc @@ -1120,12 +1120,6 @@ gfx::Rect BrowserWindowGtk::GetInstantBounds() { return gtk_util::GetWidgetScreenBounds(contents_container_->widget()); } -gfx::Rect BrowserWindowGtk::GrabWindowSnapshot(std::vector<unsigned char>* - png_representation) { - ui::GrabWindowSnapshot(window_, png_representation); - return bounds_; -} - void BrowserWindowGtk::ConfirmBrowserCloseWithPendingDownloads() { new DownloadInProgressDialogGtk(browser()); } diff --git a/chrome/browser/ui/gtk/browser_window_gtk.h b/chrome/browser/ui/gtk/browser_window_gtk.h index c8da827..371c107 100644 --- a/chrome/browser/ui/gtk/browser_window_gtk.h +++ b/chrome/browser/ui/gtk/browser_window_gtk.h @@ -131,9 +131,6 @@ class BrowserWindowGtk : public BrowserWindow, virtual void HideInstant(bool instant_is_active); virtual gfx::Rect GetInstantBounds(); - virtual gfx::Rect GrabWindowSnapshot( - std::vector<unsigned char>* png_representation); - // Overridden from NotificationObserver: virtual void Observe(NotificationType type, const NotificationSource& source, diff --git a/chrome/browser/ui/views/constrained_window_win.cc b/chrome/browser/ui/views/constrained_window_win.cc index 92dbcfa..2d4cd1b 100644 --- a/chrome/browser/ui/views/constrained_window_win.cc +++ b/chrome/browser/ui/views/constrained_window_win.cc @@ -6,7 +6,6 @@ #include <algorithm> -#include "app/win/win_util.h" #include "chrome/app/chrome_command_ids.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/tab_contents/tab_contents.h" @@ -33,6 +32,7 @@ #include "views/window/non_client_view.h" #include "views/window/window_resources.h" #include "views/window/window_shape.h" +#include "views/window/window_win.h" using base::TimeDelta; @@ -545,7 +545,7 @@ void ConstrainedWindowFrameView::InitWindowResources() { void ConstrainedWindowFrameView::InitClass() { static bool initialized = false; if (!initialized) { - title_font_ = new gfx::Font(app::win::GetWindowTitleFont()); + title_font_ = new gfx::Font(views::WindowWin::GetWindowTitleFont()); initialized = true; } } diff --git a/chrome/browser/ui/views/frame/browser_frame_win.cc b/chrome/browser/ui/views/frame/browser_frame_win.cc index 614d6da..1d16015 100644 --- a/chrome/browser/ui/views/frame/browser_frame_win.cc +++ b/chrome/browser/ui/views/frame/browser_frame_win.cc @@ -9,7 +9,6 @@ #include <set> -#include "app/win/win_util.h" #include "chrome/browser/accessibility/browser_accessibility_state.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/browser_list.h" @@ -23,6 +22,7 @@ #include "views/screen.h" #include "views/widget/widget_win.h" #include "views/window/window_delegate.h" +#include "views/window/window_win.h" // static static const int kClientEdgeThickness = 3; @@ -41,7 +41,8 @@ BrowserFrame* BrowserFrame::Create(BrowserView* browser_view, // static const gfx::Font& BrowserFrame::GetTitleFont() { - static gfx::Font* title_font = new gfx::Font(app::win::GetWindowTitleFont()); + static gfx::Font* title_font = + new gfx::Font(views::WindowWin::GetWindowTitleFont()); return *title_font; } diff --git a/chrome/browser/ui/views/frame/browser_view.cc b/chrome/browser/ui/views/frame/browser_view.cc index e6a5f8a..e68c163 100644 --- a/chrome/browser/ui/views/frame/browser_view.cc +++ b/chrome/browser/ui/views/frame/browser_view.cc @@ -84,9 +84,9 @@ #include "views/window/window.h" #if defined(OS_WIN) -#include "app/win/win_util.h" #include "chrome/browser/aeropeek_manager.h" #include "chrome/browser/jumplist_win.h" +#include "ui/base/message_box_win.h" #include "ui/base/view_prop.h" #elif defined(OS_LINUX) #include "chrome/browser/ui/views/accelerator_table_gtk.h" @@ -1143,8 +1143,8 @@ void BrowserView::ShowProfileErrorDialog(int message_id) { #if defined(OS_WIN) string16 title = l10n_util::GetStringUTF16(IDS_PRODUCT_NAME); string16 message = l10n_util::GetStringUTF16(message_id); - app::win::MessageBox(GetNativeHandle(), message, title, - MB_OK | MB_ICONWARNING | MB_TOPMOST); + ui::MessageBox(GetNativeHandle(), message, title, + MB_OK | MB_ICONWARNING | MB_TOPMOST); #elif defined(OS_LINUX) std::string title = l10n_util::GetStringUTF8(IDS_PRODUCT_NAME); std::string message = l10n_util::GetStringUTF8(message_id); @@ -1398,19 +1398,6 @@ gfx::Rect BrowserView::GetInstantBounds() { return contents_->GetPreviewBounds(); } -gfx::Rect BrowserView::GrabWindowSnapshot(std::vector<unsigned char>* - png_representation) { - views::Window* window = GetWindow(); - -#if defined(USE_X11) - ui::GrabWindowSnapshot(window->GetNativeWindow(), png_representation); -#elif defined(OS_WIN) - app::win::GrabWindowSnapshot(window->GetNativeWindow(), png_representation); -#endif - - return window->GetBounds(); -} - #if defined(OS_CHROMEOS) void BrowserView::ShowKeyboardOverlay(gfx::NativeWindow owning_window) { KeyboardOverlayDelegate::ShowDialog(owning_window); diff --git a/chrome/browser/ui/views/frame/browser_view.h b/chrome/browser/ui/views/frame/browser_view.h index 7bdb7d2..f9dd976 100644 --- a/chrome/browser/ui/views/frame/browser_view.h +++ b/chrome/browser/ui/views/frame/browser_view.h @@ -328,8 +328,6 @@ class BrowserView : public BrowserBubbleHost, virtual void ShowInstant(TabContents* preview_contents); virtual void HideInstant(bool instant_is_active); virtual gfx::Rect GetInstantBounds(); - virtual gfx::Rect GrabWindowSnapshot(std::vector<unsigned char>* - png_representation); #if defined(OS_CHROMEOS) virtual void ShowKeyboardOverlay(gfx::NativeWindow owning_window); diff --git a/chrome/browser/ui/views/tabs/tab_strip.cc b/chrome/browser/ui/views/tabs/tab_strip.cc index 4cd155c..bd35488 100644 --- a/chrome/browser/ui/views/tabs/tab_strip.cc +++ b/chrome/browser/ui/views/tabs/tab_strip.cc @@ -29,7 +29,7 @@ #include "views/window/window.h" #if defined(OS_WIN) -#include "app/win/win_util.h" +#include "views/widget/monitor_win.h" #include "views/widget/widget_win.h" #elif defined(OS_LINUX) #include "views/widget/widget_gtk.h" @@ -682,7 +682,7 @@ gfx::Rect TabStrip::GetDropBounds(int drop_index, // If the rect doesn't fit on the monitor, push the arrow to the bottom. #if defined(OS_WIN) - gfx::Rect monitor_bounds = app::win::GetMonitorBoundsForRect(drop_bounds); + gfx::Rect monitor_bounds = views::GetMonitorBoundsForRect(drop_bounds); *is_beneath = (monitor_bounds.IsEmpty() || !monitor_bounds.Contains(drop_bounds)); #else diff --git a/chrome/browser/ui/window_snapshot/window_snapshot.h b/chrome/browser/ui/window_snapshot/window_snapshot.h new file mode 100755 index 0000000..3372009 --- /dev/null +++ b/chrome/browser/ui/window_snapshot/window_snapshot.h @@ -0,0 +1,26 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_UI_WINDOW_SNAPSHOT_WINDOW_SNAPSHOT_H_ +#define CHROME_BROWSER_UI_WINDOW_SNAPSHOT_WINDOW_SNAPSHOT_H_ +#pragma once + +#include <vector> + +#include "gfx/native_widget_types.h" + +namespace gfx { + class Rect; +} + +namespace browser { + +// Grabs a snapshot of the designated window and stores a PNG representation +// into a byte vector. Returns the image bounds. +gfx::Rect GrabWindowSnapshot(gfx::NativeWindow window, + std::vector<unsigned char>* png_representation); + +} // namespace browser + +#endif // CHROME_BROWSER_UI_WINDOW_SNAPSHOT_WINDOW_SNAPSHOT_H_ diff --git a/chrome/browser/ui/window_snapshot/window_snapshot_mac.mm b/chrome/browser/ui/window_snapshot/window_snapshot_mac.mm new file mode 100755 index 0000000..deb7220 --- /dev/null +++ b/chrome/browser/ui/window_snapshot/window_snapshot_mac.mm @@ -0,0 +1,44 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/ui/window_snapshot/window_snapshot.h" + +#import <Cocoa/Cocoa.h> + +#include "base/logging.h" +#include "base/mac/scoped_cftyperef.h" +#include "base/scoped_nsobject.h" +#include "gfx/rect.h" + +namespace browser { + +gfx::Rect GrabWindowSnapshot(gfx::NativeWindow window, + std::vector<unsigned char>* png_representation) { + png_representation->clear(); + + // Make sure to grab the "window frame" view so we get current tab + + // tabstrip. + NSView* view = [[window contentView] superview]; + base::mac::ScopedCFTypeRef<CGImageRef> windowSnapshot(CGWindowListCreateImage( + CGRectNull, kCGWindowListOptionIncludingWindow, + [[view window] windowNumber], kCGWindowImageBoundsIgnoreFraming)); + if (CGImageGetWidth(windowSnapshot) <= 0) + return gfx::Rect(); + + scoped_nsobject<NSBitmapImageRep> rep( + [[NSBitmapImageRep alloc] initWithCGImage:windowSnapshot]); + NSData* data = [rep representationUsingType:NSPNGFileType properties:nil]; + const unsigned char* buf = static_cast<const unsigned char*>([data bytes]); + NSUInteger length = [data length]; + if (buf == NULL || length == 0) + return gfx::Rect(); + + png_representation->assign(buf, buf + length); + DCHECK(png_representation->size() > 0); + + return gfx::Rect(static_cast<int>([rep pixelsWide]), + static_cast<int>([rep pixelsHigh])); +} + +} // namespace browser diff --git a/chrome/browser/ui/window_snapshot/window_snapshot_mac_unittest.mm b/chrome/browser/ui/window_snapshot/window_snapshot_mac_unittest.mm new file mode 100755 index 0000000..a7a377b --- /dev/null +++ b/chrome/browser/ui/window_snapshot/window_snapshot_mac_unittest.mm @@ -0,0 +1,49 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/ui/window_snapshot/window_snapshot.h" + +#import <Cocoa/Cocoa.h> + +#include "base/scoped_nsobject.h" +#include "base/scoped_ptr.h" +#include "base/test/mock_chrome_application_mac.h" +#include "gfx/rect.h" +#include "testing/platform_test.h" + +namespace browser { +namespace { + +typedef PlatformTest GrabWindowSnapshotTest; + +TEST_F(GrabWindowSnapshotTest, TestGrabWindowSnapshot) { + // Launch a test window so we can take a snapshot. + NSRect frame = NSMakeRect(0, 0, 400, 400); + scoped_nsobject<NSWindow> window( + [[NSWindow alloc] initWithContentRect:frame + styleMask:NSBorderlessWindowMask + backing:NSBackingStoreBuffered + defer:NO]); + [window setBackgroundColor:[NSColor whiteColor]]; + [window makeKeyAndOrderFront:NSApp]; + + scoped_ptr<std::vector<unsigned char> > png_representation( + new std::vector<unsigned char>); + browser::GrabWindowSnapshot(window, png_representation.get()); + + // Copy png back into NSData object so we can make sure we grabbed a png. + scoped_nsobject<NSData> image_data( + [[NSData alloc] initWithBytes:&(*png_representation)[0] + length:png_representation->size()]); + NSBitmapImageRep* rep = [NSBitmapImageRep imageRepWithData:image_data.get()]; + EXPECT_TRUE([rep isKindOfClass:[NSBitmapImageRep class]]); + EXPECT_TRUE(CGImageGetWidth([rep CGImage]) == 400); + NSColor* color = [rep colorAtX:200 y:200]; + CGFloat red = 0, green = 0, blue = 0, alpha = 0; + [color getRed:&red green:&green blue:&blue alpha:&alpha]; + EXPECT_GE(red + green + blue, 3.0); +} + +} // namespace +} // namespace browser diff --git a/chrome/browser/ui/window_snapshot/window_snapshot_win.cc b/chrome/browser/ui/window_snapshot/window_snapshot_win.cc new file mode 100755 index 0000000..66e0071 --- /dev/null +++ b/chrome/browser/ui/window_snapshot/window_snapshot_win.cc @@ -0,0 +1,72 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/ui/window_snapshot/window_snapshot.h" + +#include "base/win/scoped_gdi_object.h" +#include "base/win/scoped_hdc.h" +#include "gfx/codec/png_codec.h" +#include "gfx/gdi_util.h" +#include "gfx/rect.h" + +namespace browser { + +gfx::Rect GrabWindowSnapshot(gfx::NativeWindow window_handle, + std::vector<unsigned char>* png_representation) { + // Create a memory DC that's compatible with the window. + HDC window_hdc = GetWindowDC(window_handle); + base::win::ScopedHDC mem_hdc(CreateCompatibleDC(window_hdc)); + + // Create a DIB that's the same size as the window. + RECT content_rect = {0, 0, 0, 0}; + ::GetWindowRect(window_handle, &content_rect); + content_rect.right++; // Match what PrintWindow wants. + int width = content_rect.right - content_rect.left; + int height = content_rect.bottom - content_rect.top; + BITMAPINFOHEADER hdr; + gfx::CreateBitmapHeader(width, height, &hdr); + unsigned char *bit_ptr = NULL; + base::win::ScopedBitmap bitmap( + CreateDIBSection(mem_hdc, + reinterpret_cast<BITMAPINFO*>(&hdr), + DIB_RGB_COLORS, + reinterpret_cast<void **>(&bit_ptr), + NULL, 0)); + + SelectObject(mem_hdc, bitmap); + // Clear the bitmap to white (so that rounded corners on windows + // show up on a white background, and strangely-shaped windows + // look reasonable). Not capturing an alpha mask saves a + // bit of space. + PatBlt(mem_hdc, 0, 0, width, height, WHITENESS); + // Grab a copy of the window + // First, see if PrintWindow is defined (it's not in Windows 2000). + typedef BOOL (WINAPI *PrintWindowPointer)(HWND, HDC, UINT); + PrintWindowPointer print_window = + reinterpret_cast<PrintWindowPointer>( + GetProcAddress(GetModuleHandle(L"User32.dll"), "PrintWindow")); + + // If PrintWindow is defined, use it. It will work on partially + // obscured windows, and works better for out of process sub-windows. + // Otherwise grab the bits we can get with BitBlt; it's better + // than nothing and will work fine in the average case (window is + // completely on screen). + if (print_window) + (*print_window)(window_handle, mem_hdc, 0); + else + BitBlt(mem_hdc, 0, 0, width, height, window_hdc, 0, 0, SRCCOPY); + + // We now have a copy of the window contents in a DIB, so + // encode it into a useful format for posting to the bug report + // server. + gfx::PNGCodec::Encode(bit_ptr, gfx::PNGCodec::FORMAT_BGRA, + width, height, width * 4, true, + png_representation); + + ReleaseDC(window_handle, window_hdc); + + return gfx::Rect(width, height); +} + +} // namespace browser diff --git a/chrome/browser/ui/window_snapshot/window_snapshot_x.cc b/chrome/browser/ui/window_snapshot/window_snapshot_x.cc new file mode 100755 index 0000000..48f8169 --- /dev/null +++ b/chrome/browser/ui/window_snapshot/window_snapshot_x.cc @@ -0,0 +1,66 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/ui/window_snapshot/window_snapshot.h" + +#include <gdk/gdkx.h> +#include <gtk/gtk.h> + +#include "base/logging.h" +#include "gfx/rect.h" +#include "ui/base/x/x11_util.h" + +namespace browser { + +static cairo_status_t SnapshotCallback( + void *closure, const unsigned char *data, unsigned int length) { + std::vector<unsigned char>* png_representation = + static_cast<std::vector<unsigned char>*>(closure); + + size_t old_size = png_representation->size(); + png_representation->resize(old_size + length); + memcpy(&(*png_representation)[old_size], data, length); + return CAIRO_STATUS_SUCCESS; +} + +gfx::Rect GrabWindowSnapshot(gfx::NativeWindow gtk_window, + std::vector<unsigned char>* png_representation) { + GdkWindow* gdk_window = GTK_WIDGET(gtk_window)->window; + Display* display = GDK_WINDOW_XDISPLAY(gdk_window); + XID win = GDK_WINDOW_XID(gdk_window); + XWindowAttributes attr; + if (XGetWindowAttributes(display, win, &attr) == 0) { + LOG(ERROR) << "Couldn't get window attributes"; + return gfx::Rect(); + } + XImage* image = XGetImage( + display, win, 0, 0, attr.width, attr.height, AllPlanes, ZPixmap); + if (!image) { + LOG(ERROR) << "Couldn't get image"; + return gfx::Rect(); + } + if (image->depth != 24) { + LOG(ERROR)<< "Unsupported image depth " << image->depth; + return gfx::Rect(); + } + cairo_surface_t* surface = + cairo_image_surface_create_for_data( + reinterpret_cast<unsigned char*>(image->data), + CAIRO_FORMAT_RGB24, + image->width, + image->height, + image->bytes_per_line); + + if (!surface) { + LOG(ERROR) << "Unable to create Cairo surface from XImage data"; + return gfx::Rect(); + } + cairo_surface_write_to_png_stream( + surface, SnapshotCallback, png_representation); + cairo_surface_destroy(surface); + + return gfx::Rect(image->width, image->height); +} + +} // namespace browser diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index 6ac0a59..7eded71 100644 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi @@ -3530,6 +3530,10 @@ 'browser/ui/window_sizer_linux.cc', 'browser/ui/window_sizer_mac.mm', 'browser/ui/window_sizer_win.cc', + 'browser/ui/window_snapshot/window_snapshot.h', + 'browser/ui/window_snapshot/window_snapshot_mac.mm', + 'browser/ui/window_snapshot/window_snapshot_win.cc', + 'browser/ui/window_snapshot/window_snapshot_x.cc', 'browser/upgrade_detector.cc', 'browser/upgrade_detector.h', 'browser/user_style_sheet_watcher.cc', diff --git a/chrome/chrome_common.gypi b/chrome/chrome_common.gypi index 354b3fb..390c610 100644 --- a/chrome/chrome_common.gypi +++ b/chrome/chrome_common.gypi @@ -159,6 +159,8 @@ 'common/sandbox_mac.mm', 'common/sandbox_policy.cc', 'common/sandbox_policy.h', + 'common/section_util_win.cc', + 'common/section_util_win.h', 'common/serialized_script_value.cc', 'common/serialized_script_value.h', 'common/set_process_title.cc', diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi index de1baf6..7e00c14 100644 --- a/chrome/chrome_tests.gypi +++ b/chrome/chrome_tests.gypi @@ -1638,6 +1638,7 @@ 'browser/ui/views/shell_dialogs_win_unittest.cc', 'browser/ui/views/status_icons/status_tray_win_unittest.cc', 'browser/ui/window_sizer_unittest.cc', + 'browser/ui/window_snapshot/window_snapshot_mac_unittest.mm', 'browser/user_style_sheet_watcher_unittest.cc', 'browser/visitedlink/visitedlink_unittest.cc', 'browser/web_applications/web_app_unittest.cc', diff --git a/chrome/common/sandbox_policy.cc b/chrome/common/sandbox_policy.cc index 501b19f..632d873 100644 --- a/chrome/common/sandbox_policy.cc +++ b/chrome/common/sandbox_policy.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -6,7 +6,6 @@ #include <string> -#include "app/win/win_util.h" #include "base/command_line.h" #include "base/debug/debugger.h" #include "base/debug/trace_event.h" diff --git a/chrome/common/section_util_win.cc b/chrome/common/section_util_win.cc new file mode 100755 index 0000000..449151c --- /dev/null +++ b/chrome/common/section_util_win.cc @@ -0,0 +1,29 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/common/section_util_win.h" + +namespace chrome { + +HANDLE GetSectionFromProcess(HANDLE section, HANDLE process, bool read_only) { + HANDLE valid_section = NULL; + DWORD access = STANDARD_RIGHTS_REQUIRED | FILE_MAP_READ; + if (!read_only) + access |= FILE_MAP_WRITE; + DuplicateHandle(process, section, GetCurrentProcess(), &valid_section, access, + FALSE, 0); + return valid_section; +} + +HANDLE GetSectionForProcess(HANDLE section, HANDLE process, bool read_only) { + HANDLE valid_section = NULL; + DWORD access = STANDARD_RIGHTS_REQUIRED | FILE_MAP_READ; + if (!read_only) + access |= FILE_MAP_WRITE; + DuplicateHandle(GetCurrentProcess(), section, process, &valid_section, access, + FALSE, 0); + return valid_section; +} + +} // namespace chrome diff --git a/chrome/common/section_util_win.h b/chrome/common/section_util_win.h new file mode 100755 index 0000000..a3c849e --- /dev/null +++ b/chrome/common/section_util_win.h @@ -0,0 +1,23 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_COMMON_SECTION_UTIL_WIN_H_ +#define CHROME_COMMON_SECTION_UTIL_WIN_H_ +#pragma once + +#include <windows.h> + +namespace chrome { + +// 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); + +// Duplicates a section handle from the current process for use in another +// process. Returns the new valid handle or NULL on failure. +HANDLE GetSectionForProcess(HANDLE section, HANDLE process, bool read_only); + +} // namespace chrome + +#endif // CHROME_COMMON_SECTION_UTIL_WIN_H_ diff --git a/chrome/plugin/webplugin_proxy.cc b/chrome/plugin/webplugin_proxy.cc index de15ce7..8f671b9 100644 --- a/chrome/plugin/webplugin_proxy.cc +++ b/chrome/plugin/webplugin_proxy.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -30,7 +30,7 @@ #endif #if defined(OS_WIN) -#include "app/win/win_util.h" +#include "chrome/common/section_util_win.h" #include "gfx/gdi_util.h" #endif @@ -535,7 +535,7 @@ void WebPluginProxy::SetWindowlessBuffer( window_rect.width(), window_rect.height(), true, - app::win::GetSectionFromProcess(windowless_buffer, + chrome::GetSectionFromProcess(windowless_buffer, channel_->renderer_handle(), false))) { windowless_canvas_.reset(); background_canvas_.reset(); @@ -548,7 +548,7 @@ void WebPluginProxy::SetWindowlessBuffer( window_rect.width(), window_rect.height(), true, - app::win::GetSectionFromProcess(background_buffer, + chrome::GetSectionFromProcess(background_buffer, channel_->renderer_handle(), false))) { windowless_canvas_.reset(); background_canvas_.reset(); diff --git a/chrome/test/test_browser_window.h b/chrome/test/test_browser_window.h index cb332db..1e9e99f 100644 --- a/chrome/test/test_browser_window.h +++ b/chrome/test/test_browser_window.h @@ -6,8 +6,6 @@ #define CHROME_TEST_TEST_BROWSER_WINDOW_H_ #pragma once -#include <vector> - #include "chrome/browser/browser_window.h" #include "chrome/test/test_location_bar.h" @@ -111,11 +109,6 @@ class TestBrowserWindow : public BrowserWindow { virtual void HideInstant(bool instant_is_active) {} virtual gfx::Rect GetInstantBounds() { return gfx::Rect(); } - virtual gfx::Rect GrabWindowSnapshot(std::vector<unsigned char>* - png_representation) { - return gfx::Rect(); - } - #if defined(OS_CHROMEOS) virtual void ShowKeyboardOverlay(gfx::NativeWindow owning_window) {} #endif diff --git a/printing/DEPS b/printing/DEPS index 1144038..c95a42a 100644 --- a/printing/DEPS +++ b/printing/DEPS @@ -1,5 +1,4 @@ include_rules = [ - "+app", # win_util::FormatSystemTime/Date. "+base", "+gfx", "+skia/ext", diff --git a/printing/printed_document_win.cc b/printing/printed_document_win.cc index 0cd0bb9..32a71a9 100644 --- a/printing/printed_document_win.cc +++ b/printing/printed_document_win.cc @@ -1,10 +1,9 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "printing/printed_document.h" -#include "app/win/win_util.h" #include "base/logging.h" #include "base/string_util.h" #include "base/utf_string_conversions.h" @@ -34,6 +33,46 @@ void DrawRect(HDC context, gfx::Rect rect) { Rectangle(context, rect.x(), rect.y(), rect.right(), rect.bottom()); } +// Creates a string interpretation of the time of day represented by the given +// SYSTEMTIME that's appropriate for the user's default locale. +// Format can be an empty string (for the default format), or a "format picture" +// as specified in the Windows documentation for GetTimeFormat(). +string16 FormatSystemTime(const SYSTEMTIME& time, const string16& format) { + // If the format string is empty, just use the default format. + LPCTSTR format_ptr = NULL; + if (!format.empty()) + format_ptr = format.c_str(); + + int buffer_size = GetTimeFormat(LOCALE_USER_DEFAULT, NULL, &time, format_ptr, + NULL, 0); + + string16 output; + GetTimeFormat(LOCALE_USER_DEFAULT, NULL, &time, format_ptr, + WriteInto(&output, buffer_size), buffer_size); + + return output; +} + +// Creates a string interpretation of the date represented by the given +// SYSTEMTIME that's appropriate for the user's default locale. +// Format can be an empty string (for the default format), or a "format picture" +// as specified in the Windows documentation for GetDateFormat(). +string16 FormatSystemDate(const SYSTEMTIME& date, const string16& format) { + // If the format string is empty, just use the default format. + LPCTSTR format_ptr = NULL; + if (!format.empty()) + format_ptr = format.c_str(); + + int buffer_size = GetDateFormat(LOCALE_USER_DEFAULT, NULL, &date, format_ptr, + NULL, 0); + + string16 output; + GetDateFormat(LOCALE_USER_DEFAULT, NULL, &date, format_ptr, + WriteInto(&output, buffer_size), buffer_size); + + return output; +} + } // namespace namespace printing { @@ -121,9 +160,9 @@ void PrintedDocument::Immutable::SetDocumentDate() { SYSTEMTIME systemtime; GetLocalTime(&systemtime); date_ = - WideToUTF16Hack(app::win::FormatSystemDate(systemtime, std::wstring())); + WideToUTF16Hack(FormatSystemDate(systemtime, std::wstring())); time_ = - WideToUTF16Hack(app::win::FormatSystemTime(systemtime, std::wstring())); + WideToUTF16Hack(FormatSystemTime(systemtime, std::wstring())); } void PrintedDocument::DrawHeaderFooter(gfx::NativeDrawingContext context, diff --git a/ui/base/message_box_win.cc b/ui/base/message_box_win.cc new file mode 100755 index 0000000..622a9d8 --- /dev/null +++ b/ui/base/message_box_win.cc @@ -0,0 +1,41 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ui/base/message_box_win.h" + +#include <windows.h> + +#include "base/base_switches.h" +#include "base/command_line.h" +#include "base/i18n/rtl.h" +#include "base/string16.h" + +namespace ui { + +// In addition to passing the RTL flags to ::MessageBox if we are running in an +// RTL locale, we need to make sure that LTR strings are rendered correctly by +// adding the appropriate Unicode directionality marks. +int MessageBox(HWND hwnd, + const string16& text, + const string16& caption, + UINT flags) { + if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kNoMessageBox)) + return IDOK; + + UINT actual_flags = flags; + if (base::i18n::IsRTL()) + actual_flags |= MB_RIGHT | MB_RTLREADING; + + string16 localized_text = text; + base::i18n::AdjustStringForLocaleDirection(&localized_text); + const wchar_t* text_ptr = localized_text.c_str(); + + string16 localized_caption = caption; + base::i18n::AdjustStringForLocaleDirection(&localized_caption); + const wchar_t* caption_ptr = localized_caption.c_str(); + + return ::MessageBox(hwnd, text_ptr, caption_ptr, actual_flags); +} + +} // namespace ui diff --git a/ui/base/message_box_win.h b/ui/base/message_box_win.h new file mode 100755 index 0000000..f9011e6 --- /dev/null +++ b/ui/base/message_box_win.h @@ -0,0 +1,26 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef UI_BASE_MESSAGE_BOX_WIN_H_ +#define UI_BASE_MESSAGE_BOX_WIN_H_ +#pragma once + +#include <windows.h> + +#include "base/string16.h" + +namespace ui { + +// A wrapper around Windows' MessageBox function. Using a Chrome specific +// MessageBox function allows us to control certain RTL locale flags so that +// callers don't have to worry about adding these flags when running in a +// right-to-left locale. +int MessageBox(HWND hwnd, + const string16& text, + const string16& caption, + UINT flags); + +} // namespace ui + +#endif // UI_BASE_MESSAGE_BOX_WIN_H_ diff --git a/ui/base/x/x11_util.cc b/ui/base/x/x11_util.cc index f7222fc..1232bc8 100644 --- a/ui/base/x/x11_util.cc +++ b/ui/base/x/x11_util.cc @@ -687,54 +687,6 @@ bool GetWindowManagerName(std::string* wm_name) { return !got_error && result; } -static cairo_status_t SnapshotCallback( - void *closure, const unsigned char *data, unsigned int length) { - std::vector<unsigned char>* png_representation = - static_cast<std::vector<unsigned char>*>(closure); - - size_t old_size = png_representation->size(); - png_representation->resize(old_size + length); - memcpy(&(*png_representation)[old_size], data, length); - return CAIRO_STATUS_SUCCESS; -} - -void GrabWindowSnapshot(GtkWindow* gtk_window, - std::vector<unsigned char>* png_representation) { - GdkWindow* gdk_window = GTK_WIDGET(gtk_window)->window; - Display* display = GDK_WINDOW_XDISPLAY(gdk_window); - XID win = GDK_WINDOW_XID(gdk_window); - XWindowAttributes attr; - if (XGetWindowAttributes(display, win, &attr) == 0) { - LOG(ERROR) << "Couldn't get window attributes"; - return; - } - XImage* image = XGetImage( - display, win, 0, 0, attr.width, attr.height, AllPlanes, ZPixmap); - if (!image) { - LOG(ERROR) << "Couldn't get image"; - return; - } - if (image->depth != 24) { - LOG(ERROR)<< "Unsupported image depth " << image->depth; - return; - } - cairo_surface_t* surface = - cairo_image_surface_create_for_data( - reinterpret_cast<unsigned char*>(image->data), - CAIRO_FORMAT_RGB24, - image->width, - image->height, - image->bytes_per_line); - - if (!surface) { - LOG(ERROR) << "Unable to create Cairo surface from XImage data"; - return; - } - cairo_surface_write_to_png_stream( - surface, SnapshotCallback, png_representation); - cairo_surface_destroy(surface); -} - bool ChangeWindowDesktop(XID window, XID destination) { int desktop; if (!GetWindowDesktop(destination, &desktop)) diff --git a/ui/base/x/x11_util.h b/ui/base/x/x11_util.h index 3284fcb..e323d8b 100644 --- a/ui/base/x/x11_util.h +++ b/ui/base/x/x11_util.h @@ -20,7 +20,6 @@ typedef unsigned long Atom; typedef struct _GdkDrawable GdkWindow; typedef struct _GtkWidget GtkWidget; -typedef struct _GtkWindow GtkWindow; typedef unsigned long XID; typedef unsigned long XSharedMemoryId; // ShmSeg in the X headers. typedef struct _XDisplay Display; @@ -171,11 +170,6 @@ bool GetWindowParent(XID* parent_window, bool* parent_is_root, XID window); // Get the window manager name. bool GetWindowManagerName(std::string* name); -// Grabs a snapshot of the designated window and stores a PNG representation -// into a byte vector. -void GrabWindowSnapshot(GtkWindow* gdk_window, - std::vector<unsigned char>* png_representation); - // Change desktop for |window| to the desktop of |destination| window. bool ChangeWindowDesktop(XID window, XID destination); diff --git a/views/controls/textfield/native_textfield_win.cc b/views/controls/textfield/native_textfield_win.cc index ecdb38f..14c5317 100644 --- a/views/controls/textfield/native_textfield_win.cc +++ b/views/controls/textfield/native_textfield_win.cc @@ -6,7 +6,6 @@ #include <algorithm> -#include "app/win/win_util.h" #include "base/i18n/rtl.h" #include "base/string_util.h" #include "base/utf_string_conversions.h" @@ -131,6 +130,37 @@ NativeTextfieldWin::~NativeTextfieldWin() { DestroyWindow(); } +// static +bool NativeTextfieldWin::IsDoubleClick(const POINT& origin, + const POINT& current, + DWORD elapsed_time) { + // The CXDOUBLECLK and CYDOUBLECLK system metrics describe the width and + // height of a rectangle around the origin position, inside of which clicks + // within the double click time are considered double clicks. + return (elapsed_time <= GetDoubleClickTime()) && + (abs(current.x - origin.x) <= (GetSystemMetrics(SM_CXDOUBLECLK) / 2)) && + (abs(current.y - origin.y) <= (GetSystemMetrics(SM_CYDOUBLECLK) / 2)); +} + +// static +bool NativeTextfieldWin::IsNumPadDigit(int key_code, bool extended_key) { + if (key_code >= VK_NUMPAD0 && key_code <= VK_NUMPAD9) + return true; + + // Check for num pad keys without NumLock. + // Note: there is no easy way to know if a the key that was pressed comes from + // the num pad or the rest of the keyboard. Investigating how + // TranslateMessage() generates the WM_KEYCHAR from an + // ALT + <NumPad sequences> it appears it looks at the extended key flag + // (which is on if the key pressed comes from one of the 3 clusters to + // the left of the numeric keypad). So we use it as well. + return !extended_key && + ((key_code >= VK_PRIOR && key_code <= VK_DOWN) || // All keys but 5 + // and 0. + (key_code == VK_CLEAR) || // Key 5. + (key_code == VK_INSERT)); // Key 0. +} + void NativeTextfieldWin::AttachHack() { // See the code in textfield.cc that calls this for why this is here. container_view_->set_focus_view(textfield_); @@ -678,8 +708,8 @@ void NativeTextfieldWin::OnLButtonDown(UINT keys, const CPoint& point) { // double_click_time_ from the current message's time even if the timer has // wrapped in between. const bool is_triple_click = tracking_double_click_ && - app::win::IsDoubleClick(double_click_point_, point, - GetCurrentMessage()->time - double_click_time_); + IsDoubleClick(double_click_point_, point, + GetCurrentMessage()->time - double_click_time_); tracking_double_click_ = false; ScopedFreeze freeze(this, GetTextObjectModel()); diff --git a/views/controls/textfield/native_textfield_win.h b/views/controls/textfield/native_textfield_win.h index efc5d57..b0c8902 100644 --- a/views/controls/textfield/native_textfield_win.h +++ b/views/controls/textfield/native_textfield_win.h @@ -43,6 +43,18 @@ class NativeTextfieldWin explicit NativeTextfieldWin(Textfield* parent); ~NativeTextfieldWin(); + // Returns true if the current point is close enough to the origin point in + // space and time that it would be considered a double click. + static bool IsDoubleClick(const POINT& origin, + const POINT& current, + DWORD elapsed_time); + + // Returns true if the virtual key code is a digit coming from the numeric + // keypad (with or without NumLock on). |extended_key| should be set to the + // extended key flag specified in the WM_KEYDOWN/UP where the |key_code| + // originated. + static bool IsNumPadDigit(int key_code, bool extended_key); + // See the code in textfield.cc that calls this for why this is here. void AttachHack(); diff --git a/views/controls/textfield/textfield.cc b/views/controls/textfield/textfield.cc index a228ed9..cbd6f52 100644 --- a/views/controls/textfield/textfield.cc +++ b/views/controls/textfield/textfield.cc @@ -21,7 +21,6 @@ #if defined(OS_LINUX) #include "ui/base/keycodes/keyboard_code_conversion_gtk.h" #elif defined(OS_WIN) -#include "app/win/win_util.h" #include "base/win/win_util.h" // TODO(beng): this should be removed when the OS_WIN hack from // ViewHierarchyChanged is removed. @@ -318,7 +317,7 @@ bool Textfield::SkipDefaultKeyEventProcessing(const KeyEvent& e) { // We don't translate accelerators for ALT + NumPad digit on Windows, they are // used for entering special characters. We do translate alt-home. if (e.IsAltDown() && (key != ui::VKEY_HOME) && - app::win::IsNumPadDigit(key, e.IsExtendedKey())) + NativeTextfieldWin::IsNumPadDigit(key, e.IsExtendedKey())) return true; #endif return false; diff --git a/views/views.gyp b/views/views.gyp index 5a437d9..9be2292 100644 --- a/views/views.gyp +++ b/views/views.gyp @@ -336,6 +336,8 @@ 'widget/tooltip_manager.h', 'widget/tooltip_window_gtk.cc', 'widget/tooltip_window_gtk.h', + 'widget/monitor_win.cc', + 'widget/monitor_win.h', 'widget/widget.h', 'widget/widget_gtk.cc', 'widget/widget_gtk.h', @@ -468,6 +470,7 @@ 'test/test_views_delegate.h', 'view_unittest.cc', 'widget/widget_win_unittest.cc', + 'window/window_win_unittest.cc', '<(SHARED_INTERMEDIATE_DIR)/app/app_resources/app_resources.rc', ], diff --git a/views/widget/monitor_win.cc b/views/widget/monitor_win.cc new file mode 100755 index 0000000..848adfa --- /dev/null +++ b/views/widget/monitor_win.cc @@ -0,0 +1,27 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "views/widget/monitor_win.h" + +#include <windows.h> + +#include "base/logging.h" +#include "gfx/rect.h" + +namespace views { + +gfx::Rect GetMonitorBoundsForRect(const gfx::Rect& rect) { + RECT p_rect = rect.ToRECT(); + HMONITOR monitor = MonitorFromRect(&p_rect, MONITOR_DEFAULTTONEAREST); + if (monitor) { + MONITORINFO mi = {0}; + mi.cbSize = sizeof(mi); + GetMonitorInfo(monitor, &mi); + return gfx::Rect(mi.rcWork); + } + NOTREACHED(); + return gfx::Rect(); +} + +} // namespace views diff --git a/views/widget/monitor_win.h b/views/widget/monitor_win.h new file mode 100755 index 0000000..b1cdf24 --- /dev/null +++ b/views/widget/monitor_win.h @@ -0,0 +1,21 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef VIEWS_WIDGET_MONITOR_WIN_H_ +#define VIEWS_WIDGET_MONITOR_WIN_H_ +#pragma once + +namespace gfx { +class Rect; +} + +namespace views { + +// Returns the bounds for the monitor that contains the largest area of +// intersection with the specified rectangle. +gfx::Rect GetMonitorBoundsForRect(const gfx::Rect& rect); + +} // namespace views + +#endif // VIEWS_WIDGET_MONITOR_WIN_H_ diff --git a/views/widget/tooltip_manager_win.cc b/views/widget/tooltip_manager_win.cc index 0ea8187..854275e 100644 --- a/views/widget/tooltip_manager_win.cc +++ b/views/widget/tooltip_manager_win.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -7,7 +7,6 @@ #include <windowsx.h> #include <limits> -#include "app/win/win_util.h" #include "base/i18n/rtl.h" #include "base/logging.h" #include "base/message_loop.h" @@ -15,6 +14,7 @@ #include "ui/base/l10n/l10n_util_win.h" #include "views/screen.h" #include "views/view.h" +#include "views/widget/monitor_win.h" #include "views/widget/root_view.h" #include "views/widget/widget.h" @@ -228,7 +228,7 @@ bool TooltipManagerWin::SetTooltipPosition(int text_x, int text_y) { // doesn't, return false so that windows positions the tooltip at the // default location. gfx::Rect monitor_bounds = - app::win::GetMonitorBoundsForRect(gfx::Rect(bounds.left,bounds.right, + views::GetMonitorBoundsForRect(gfx::Rect(bounds.left,bounds.right, 0, 0)); if (!monitor_bounds.Contains(gfx::Rect(bounds))) { return false; @@ -356,7 +356,7 @@ void TooltipManagerWin::ShowKeyboardTooltip(View* focused_view) { screen_point.y() + focused_bounds.height() + line_count * tooltip_height_ }; gfx::Rect monitor_bounds = - app::win::GetMonitorBoundsForRect(gfx::Rect(rect_bounds)); + views::GetMonitorBoundsForRect(gfx::Rect(rect_bounds)); rect_bounds = gfx::Rect(rect_bounds).AdjustToFit(monitor_bounds).ToRECT(); ::SetWindowPos(keyboard_tooltip_hwnd_, NULL, rect_bounds.left, rect_bounds.top, 0, 0, diff --git a/views/widget/widget_win.cc b/views/widget/widget_win.cc index 2f7603a..a7731e5 100644 --- a/views/widget/widget_win.cc +++ b/views/widget/widget_win.cc @@ -6,7 +6,6 @@ #include <dwmapi.h> -#include "app/win/win_util.h" #include "base/string_util.h" #include "base/win/windows_version.h" #include "gfx/canvas_skia.h" @@ -35,6 +34,17 @@ using ui::ViewProp; +namespace { + +// Returns whether the specified window is the current active window. +bool IsWindowActive(HWND hwnd) { + WINDOWINFO info; + return ::GetWindowInfo(hwnd, &info) && + ((info.dwWindowStatus & WS_ACTIVECAPTION) != 0); +} + +} // namespace + namespace views { // Property used to link the HWND to its RootView. @@ -407,7 +417,7 @@ bool WidgetWin::IsVisible() const { } bool WidgetWin::IsActive() const { - return app::win::IsWindowActive(hwnd()); + return IsWindowActive(hwnd()); } bool WidgetWin::IsAccessibleWidget() const { diff --git a/views/window/custom_frame_view.cc b/views/window/custom_frame_view.cc index fe2fc30..edc9acf 100644 --- a/views/window/custom_frame_view.cc +++ b/views/window/custom_frame_view.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -21,7 +21,7 @@ #endif #if defined(OS_WIN) -#include "app/win/win_util.h" +#include "views/window/window_win.h" #endif namespace views { @@ -571,7 +571,7 @@ void CustomFrameView::InitClass() { static bool initialized = false; if (!initialized) { #if defined(OS_WIN) - title_font_ = new gfx::Font(app::win::GetWindowTitleFont()); + title_font_ = new gfx::Font(WindowWin::GetWindowTitleFont()); #elif defined(OS_LINUX) // TODO(ben): need to resolve what font this is. title_font_ = new gfx::Font(); diff --git a/views/window/window_win.cc b/views/window/window_win.cc index dff4527..64dde6c 100644 --- a/views/window/window_win.cc +++ b/views/window/window_win.cc @@ -7,14 +7,16 @@ #include <dwmapi.h> #include <shellapi.h> -#include "app/win/win_util.h" #include "base/i18n/rtl.h" +#include "base/win/scoped_gdi_object.h" +#include "base/win/win_util.h" #include "base/win/windows_version.h" #include "gfx/canvas_skia_paint.h" #include "gfx/font.h" #include "gfx/icon_util.h" #include "gfx/path.h" #include "ui/base/keycodes/keyboard_code_conversion_win.h" +#include "ui/base/l10n/l10n_util_win.h" #include "ui/base/theme_provider.h" #include "ui/base/win/hwnd_util.h" #include "views/accessibility/view_accessibility.h" @@ -29,6 +31,9 @@ namespace { static const int kDragFrameWindowAlpha = 200; +// The thickness of an auto-hide taskbar in pixels. +static const int kAutoHideTaskbarThicknessPx = 2; + bool GetMonitorAndRects(const RECT& rect, HMONITOR* monitor, gfx::Rect* monitor_rect, @@ -88,18 +93,72 @@ void SetChildBounds(HWND child_window, HWND parent_window, } gfx::Rect actual_bounds = bounds; - app::win::EnsureRectIsVisibleInRect(gfx::Rect(parent_rect), &actual_bounds, - padding); + views::internal::EnsureRectIsVisibleInRect(gfx::Rect(parent_rect), + &actual_bounds, padding); SetWindowPos(child_window, insert_after_window, actual_bounds.x(), actual_bounds.y(), actual_bounds.width(), actual_bounds.height(), flags); } +// Returns true if edge |edge| (one of ABE_LEFT, TOP, RIGHT, or BOTTOM) of +// monitor |monitor| has an auto-hiding taskbar that's always-on-top. +bool EdgeHasTopmostAutoHideTaskbar(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) && (monitor != NULL) && + (MonitorFromWindow(taskbar, MONITOR_DEFAULTTONULL) == monitor) && + (GetWindowLong(taskbar, GWL_EXSTYLE) & WS_EX_TOPMOST); +} + } // namespace namespace views { +namespace internal { + +void EnsureRectIsVisibleInRect(const gfx::Rect& parent_rect, + gfx::Rect* child_rect, + int padding) { + DCHECK(child_rect); + + // We use padding here because it allows some of the original web page to + // bleed through around the edges. + int twice_padding = padding * 2; + + // FIRST, clamp width and height so we don't open child windows larger than + // the containing parent. + if (child_rect->width() > (parent_rect.width() + twice_padding)) + child_rect->set_width(std::max(0, parent_rect.width() - twice_padding)); + if (child_rect->height() > parent_rect.height() + twice_padding) + child_rect->set_height(std::max(0, parent_rect.height() - twice_padding)); + + // SECOND, clamp x,y position to padding,padding so we don't position child + // windows in hyperspace. + // TODO(mpcomplete): I don't see what the second check in each 'if' does that + // isn't handled by the LAST set of 'ifs'. Maybe we can remove it. + if (child_rect->x() < parent_rect.x() || + child_rect->x() > parent_rect.right()) { + child_rect->set_x(parent_rect.x() + padding); + } + if (child_rect->y() < parent_rect.y() || + child_rect->y() > parent_rect.bottom()) { + child_rect->set_y(parent_rect.y() + padding); + } + + // LAST, nudge the window back up into the client area if its x,y position is + // within the parent bounds but its width/height place it off-screen. + if (child_rect->bottom() > parent_rect.bottom()) + child_rect->set_y(parent_rect.bottom() - child_rect->height() - padding); + if (child_rect->right() > parent_rect.right()) + child_rect->set_x(parent_rect.right() - child_rect->width() - padding); +} + +} // namespace internal + // A scoping class that prevents a window from being able to redraw in response // to invalidations that may occur within it for the lifetime of the object. // @@ -242,41 +301,6 @@ static BOOL CALLBACK SendDwmCompositionChanged(HWND window, LPARAM param) { } } // namespace -void WindowWin::FrameTypeChanged() { - if (base::win::GetVersion() >= base::win::VERSION_VISTA) { - // We need to toggle the rendering policy of the DWM/glass frame as we - // change from opaque to glass. "Non client rendering enabled" means that - // the DWM's glass non-client rendering is enabled, which is why - // 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 = - non_client_view_->UseNativeFrame() ? 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); - - // The frame type change results in the client rect changing size, but this - // does not explicitly send a WM_SIZE, so we need to force the root view to - // be resized now. - LayoutRootView(); - - // Update the non-client view with the correct frame view for the active frame - // type. - non_client_view_->UpdateFrame(); - - // WM_DWMCOMPOSITIONCHANGED is only sent to top level windows, however we want - // to notify our children too, since we can have MDI child windows who need to - // update their appearance. - EnumChildWindows(GetNativeView(), &SendDwmCompositionChanged, NULL); -} - //////////////////////////////////////////////////////////////////////////////// // WindowWin, Window implementation: @@ -544,6 +568,53 @@ bool WindowWin::ShouldUseNativeFrame() const { return tp->ShouldUseNativeFrame(); } +void WindowWin::FrameTypeChanged() { + // Called when the frame type could possibly be changing (theme change or + // DWM composition change). + if (base::win::GetVersion() >= base::win::VERSION_VISTA) { + // We need to toggle the rendering policy of the DWM/glass frame as we + // change from opaque to glass. "Non client rendering enabled" means that + // the DWM's glass non-client rendering is enabled, which is why + // 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 = + non_client_view_->UseNativeFrame() ? 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); + + // The frame type change results in the client rect changing size, but this + // does not explicitly send a WM_SIZE, so we need to force the root view to + // be resized now. + LayoutRootView(); + + // Update the non-client view with the correct frame view for the active frame + // type. + non_client_view_->UpdateFrame(); + + // WM_DWMCOMPOSITIONCHANGED is only sent to top level windows, however we want + // to notify our children too, since we can have MDI child windows who need to + // update their appearance. + EnumChildWindows(GetNativeView(), &SendDwmCompositionChanged, NULL); +} + + +// static +gfx::Font WindowWin::GetWindowTitleFont() { + NONCLIENTMETRICS ncm; + base::win::GetNonClientMetrics(&ncm); + l10n_util::AdjustUIFont(&(ncm.lfCaptionFont)); + base::win::ScopedHFONT caption_font(CreateFontIndirect(&(ncm.lfCaptionFont))); + return gfx::Font(caption_font); +} + /////////////////////////////////////////////////////////////////////////////// // WindowWin, protected: @@ -843,9 +914,9 @@ LRESULT WindowWin::OnNCCalcSize(BOOL mode, LPARAM l_param) { return 0; } } - if (app::win::EdgeHasTopmostAutoHideTaskbar(ABE_LEFT, monitor)) - client_rect->left += app::win::kAutoHideTaskbarThicknessPx; - if (app::win::EdgeHasTopmostAutoHideTaskbar(ABE_TOP, monitor)) { + if (EdgeHasTopmostAutoHideTaskbar(ABE_LEFT, monitor)) + client_rect->left += kAutoHideTaskbarThicknessPx; + if (EdgeHasTopmostAutoHideTaskbar(ABE_TOP, monitor)) { if (GetNonClientView()->UseNativeFrame()) { // Tricky bit. Due to a bug in DwmDefWindowProc()'s handling of // WM_NCHITTEST, having any nonclient area atop the window causes the @@ -858,13 +929,13 @@ LRESULT WindowWin::OnNCCalcSize(BOOL mode, LPARAM l_param) { // be no better solution. --client_rect->bottom; } else { - client_rect->top += app::win::kAutoHideTaskbarThicknessPx; + client_rect->top += kAutoHideTaskbarThicknessPx; } } - if (app::win::EdgeHasTopmostAutoHideTaskbar(ABE_RIGHT, monitor)) - client_rect->right -= app::win::kAutoHideTaskbarThicknessPx; - if (app::win::EdgeHasTopmostAutoHideTaskbar(ABE_BOTTOM, monitor)) - client_rect->bottom -= app::win::kAutoHideTaskbarThicknessPx; + if (EdgeHasTopmostAutoHideTaskbar(ABE_RIGHT, monitor)) + client_rect->right -= kAutoHideTaskbarThicknessPx; + if (EdgeHasTopmostAutoHideTaskbar(ABE_BOTTOM, monitor)) + client_rect->bottom -= kAutoHideTaskbarThicknessPx; // We cannot return WVR_REDRAW when there is nonclient area, or Windows // exhibits bugs where client pixels and child HWNDs are mispositioned by diff --git a/views/window/window_win.h b/views/window/window_win.h index 37d56d1..6b20667a 100644 --- a/views/window/window_win.h +++ b/views/window/window_win.h @@ -10,12 +10,24 @@ #include "views/window/window.h" namespace gfx { +class Font; class Point; class Size; }; namespace views { +namespace internal { +// This is exposed only for testing + +// Adjusts the value of |child_rect| if necessary to ensure that it is +// completely visible within |parent_rect|. +void EnsureRectIsVisibleInRect(const gfx::Rect& parent_rect, + gfx::Rect* child_rect, + int padding); + +} // namespace internal + class Client; class WindowDelegate; @@ -45,10 +57,6 @@ class WindowWin : public WidgetWin, // Executes the specified SC_command. void ExecuteSystemMenuCommand(int command); - // Called when the frame type could possibly be changing (theme change or - // DWM composition change). - void FrameTypeChanged(); - // Accessors and setters for various properties. HWND owning_window() const { return owning_hwnd_; } void set_focus_on_creation(bool focus_on_creation) { @@ -89,6 +97,10 @@ class WindowWin : public WidgetWin, virtual ClientView* GetClientView() const; virtual gfx::NativeWindow GetNativeWindow() const; virtual bool ShouldUseNativeFrame() const; + virtual void FrameTypeChanged(); + + // Returns the system set window title font. + static gfx::Font GetWindowTitleFont(); protected: friend Window; diff --git a/app/win/win_util_unittest.cc b/views/window/window_win_unittest.cc index 0dc4568..0e1f037 100644 --- a/app/win/win_util_unittest.cc +++ b/views/window/window_win_unittest.cc @@ -1,59 +1,58 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "app/win/win_util.h" +#include "views/window/window_win.h" + #include "gfx/rect.h" #include "testing/gtest/include/gtest/gtest.h" -namespace app { -namespace win { +namespace views { -TEST(WinUtilTest, EnsureRectIsVisibleInRect) { +TEST(WindowWinTest, EnsureRectIsVisibleInRect) { gfx::Rect parent_rect(0, 0, 500, 400); { // Child rect x < 0 gfx::Rect child_rect(-50, 20, 100, 100); - EnsureRectIsVisibleInRect(parent_rect, &child_rect, 10); + internal::EnsureRectIsVisibleInRect(parent_rect, &child_rect, 10); EXPECT_EQ(gfx::Rect(10, 20, 100, 100), child_rect); } { // Child rect y < 0 gfx::Rect child_rect(20, -50, 100, 100); - EnsureRectIsVisibleInRect(parent_rect, &child_rect, 10); + internal::EnsureRectIsVisibleInRect(parent_rect, &child_rect, 10); EXPECT_EQ(gfx::Rect(20, 10, 100, 100), child_rect); } { // Child rect right > parent_rect.right gfx::Rect child_rect(450, 20, 100, 100); - EnsureRectIsVisibleInRect(parent_rect, &child_rect, 10); + internal::EnsureRectIsVisibleInRect(parent_rect, &child_rect, 10); EXPECT_EQ(gfx::Rect(390, 20, 100, 100), child_rect); } { // Child rect bottom > parent_rect.bottom gfx::Rect child_rect(20, 350, 100, 100); - EnsureRectIsVisibleInRect(parent_rect, &child_rect, 10); + internal::EnsureRectIsVisibleInRect(parent_rect, &child_rect, 10); EXPECT_EQ(gfx::Rect(20, 290, 100, 100), child_rect); } { // Child rect width > parent_rect.width gfx::Rect child_rect(20, 20, 700, 100); - EnsureRectIsVisibleInRect(parent_rect, &child_rect, 10); + internal::EnsureRectIsVisibleInRect(parent_rect, &child_rect, 10); EXPECT_EQ(gfx::Rect(20, 20, 480, 100), child_rect); } { // Child rect height > parent_rect.height gfx::Rect child_rect(20, 20, 100, 700); - EnsureRectIsVisibleInRect(parent_rect, &child_rect, 10); + internal::EnsureRectIsVisibleInRect(parent_rect, &child_rect, 10); EXPECT_EQ(gfx::Rect(20, 20, 100, 380), child_rect); } } -} // namespace win -} // namespace app +} // namespace views |