diff options
author | ben@chromium.org <ben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-06-09 19:03:44 +0000 |
---|---|---|
committer | ben@chromium.org <ben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-06-09 19:03:44 +0000 |
commit | d27987c387d44489719c493491a49bb3571957c6 (patch) | |
tree | 7765c5f774097c90ab06c533727d7dc439c570b9 /views/window | |
parent | 4f16c20c532b714ececacac1dbd240b5e6cee5cc (diff) | |
download | chromium_src-d27987c387d44489719c493491a49bb3571957c6.zip chromium_src-d27987c387d44489719c493491a49bb3571957c6.tar.gz chromium_src-d27987c387d44489719c493491a49bb3571957c6.tar.bz2 |
Move last of event handlers down to NativeWidgetWin/Gtk.
BUG=72040
TEST=none
Review URL: http://codereview.chromium.org/7129022
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@88564 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'views/window')
-rw-r--r-- | views/window/native_window.h | 3 | ||||
-rw-r--r-- | views/window/native_window_delegate.h | 9 | ||||
-rw-r--r-- | views/window/native_window_gtk.cc | 203 | ||||
-rw-r--r-- | views/window/native_window_gtk.h | 43 | ||||
-rw-r--r-- | views/window/native_window_win.cc | 469 | ||||
-rw-r--r-- | views/window/native_window_win.h | 61 | ||||
-rw-r--r-- | views/window/window.cc | 103 | ||||
-rw-r--r-- | views/window/window.h | 25 |
8 files changed, 3 insertions, 913 deletions
diff --git a/views/window/native_window.h b/views/window/native_window.h index 278a54f..de5cce8 100644 --- a/views/window/native_window.h +++ b/views/window/native_window.h @@ -44,9 +44,6 @@ class NativeWindow { protected: friend class Window; - - // Makes the NativeWindow modal. - virtual void BecomeModal() = 0; }; } // namespace views diff --git a/views/window/native_window_delegate.h b/views/window/native_window_delegate.h index a317f7d..41621ac 100644 --- a/views/window/native_window_delegate.h +++ b/views/window/native_window_delegate.h @@ -23,15 +23,6 @@ class NativeWindowDelegate { public: virtual ~NativeWindowDelegate() {} - // Returns true if the window is modal. - virtual bool IsModal() const = 0; - - // Returns true if the window is a dialog box. - virtual bool IsDialogBox() const = 0; - - // Called just after the NativeWindow has been created. - virtual void OnNativeWindowCreated(const gfx::Rect& bounds) = 0; - // virtual Window* AsWindow() = 0; diff --git a/views/window/native_window_gtk.cc b/views/window/native_window_gtk.cc index 99a4f8a..2ca707a 100644 --- a/views/window/native_window_gtk.cc +++ b/views/window/native_window_gtk.cc @@ -6,7 +6,6 @@ #include "base/i18n/rtl.h" #include "base/utf_string_conversions.h" -#include "ui/gfx/gtk_util.h" #include "ui/gfx/path.h" #include "ui/gfx/rect.h" #include "views/events/event.h" @@ -15,71 +14,11 @@ #include "views/window/non_client_view.h" #include "views/window/window_delegate.h" -namespace { - -// Converts a Windows-style hit test result code into a GDK window edge. -GdkWindowEdge HitTestCodeToGDKWindowEdge(int hittest_code) { - switch (hittest_code) { - case HTBOTTOM: - return GDK_WINDOW_EDGE_SOUTH; - case HTBOTTOMLEFT: - return GDK_WINDOW_EDGE_SOUTH_WEST; - case HTBOTTOMRIGHT: - case HTGROWBOX: - return GDK_WINDOW_EDGE_SOUTH_EAST; - case HTLEFT: - return GDK_WINDOW_EDGE_WEST; - case HTRIGHT: - return GDK_WINDOW_EDGE_EAST; - case HTTOP: - return GDK_WINDOW_EDGE_NORTH; - case HTTOPLEFT: - return GDK_WINDOW_EDGE_NORTH_WEST; - case HTTOPRIGHT: - return GDK_WINDOW_EDGE_NORTH_EAST; - default: - NOTREACHED(); - break; - } - // Default to something defaultish. - return HitTestCodeToGDKWindowEdge(HTGROWBOX); -} - -// Converts a Windows-style hit test result code into a GDK cursor type. -GdkCursorType HitTestCodeToGdkCursorType(int hittest_code) { - switch (hittest_code) { - case HTBOTTOM: - return GDK_BOTTOM_SIDE; - case HTBOTTOMLEFT: - return GDK_BOTTOM_LEFT_CORNER; - case HTBOTTOMRIGHT: - case HTGROWBOX: - return GDK_BOTTOM_RIGHT_CORNER; - case HTLEFT: - return GDK_LEFT_SIDE; - case HTRIGHT: - return GDK_RIGHT_SIDE; - case HTTOP: - return GDK_TOP_SIDE; - case HTTOPLEFT: - return GDK_TOP_LEFT_CORNER; - case HTTOPRIGHT: - return GDK_TOP_RIGHT_CORNER; - default: - break; - } - // Default to something defaultish. - return GDK_LEFT_PTR; -} - -} // namespace - namespace views { NativeWindowGtk::NativeWindowGtk(internal::NativeWindowDelegate* delegate) : NativeWidgetGtk(delegate->AsNativeWidgetDelegate()), - delegate_(delegate), - window_closed_(false) { + delegate_(delegate) { is_window_ = true; } @@ -87,114 +26,6 @@ NativeWindowGtk::~NativeWindowGtk() { } //////////////////////////////////////////////////////////////////////////////// -// NativeWindowGtk, NativeWidgetGtk overrides: - -gboolean NativeWindowGtk::OnButtonPress(GtkWidget* widget, - GdkEventButton* event) { - GdkEventButton transformed_event = *event; - MouseEvent mouse_event(TransformEvent(&transformed_event)); - - int hittest_code = - GetWindow()->non_client_view()->NonClientHitTest(mouse_event.location()); - switch (hittest_code) { - case HTCAPTION: { - // Start dragging if the mouse event is a single click and *not* a right - // click. If it is a right click, then pass it through to - // NativeWidgetGtk::OnButtonPress so that View class can show ContextMenu - // upon a mouse release event. We only start drag on single clicks as we - // get a crash in Gtk on double/triple clicks. - if (event->type == GDK_BUTTON_PRESS && - !mouse_event.IsOnlyRightMouseButton()) { - gfx::Point screen_point(event->x, event->y); - View::ConvertPointToScreen(GetWindow()->GetRootView(), &screen_point); - gtk_window_begin_move_drag(GetNativeWindow(), event->button, - screen_point.x(), screen_point.y(), - event->time); - return TRUE; - } - break; - } - case HTBOTTOM: - case HTBOTTOMLEFT: - case HTBOTTOMRIGHT: - case HTGROWBOX: - case HTLEFT: - case HTRIGHT: - case HTTOP: - case HTTOPLEFT: - case HTTOPRIGHT: { - gfx::Point screen_point(event->x, event->y); - View::ConvertPointToScreen(GetWindow()->GetRootView(), &screen_point); - // TODO(beng): figure out how to get a good minimum size. - gtk_widget_set_size_request(GetNativeView(), 100, 100); - gtk_window_begin_resize_drag(GetNativeWindow(), - HitTestCodeToGDKWindowEdge(hittest_code), - event->button, screen_point.x(), - screen_point.y(), event->time); - return TRUE; - } - default: - // Everything else falls into standard client event handling... - break; - } - return NativeWidgetGtk::OnButtonPress(widget, event); -} - -gboolean NativeWindowGtk::OnConfigureEvent(GtkWidget* widget, - GdkEventConfigure* event) { - SaveWindowPosition(); - return FALSE; -} - -gboolean NativeWindowGtk::OnMotionNotify(GtkWidget* widget, - GdkEventMotion* event) { - GdkEventMotion transformed_event = *event; - TransformEvent(&transformed_event); - gfx::Point translated_location(transformed_event.x, transformed_event.y); - - // Update the cursor for the screen edge. - int hittest_code = - GetWindow()->non_client_view()->NonClientHitTest(translated_location); - if (hittest_code != HTCLIENT) { - GdkCursorType cursor_type = HitTestCodeToGdkCursorType(hittest_code); - gdk_window_set_cursor(widget->window, gfx::GetCursor(cursor_type)); - } - - return NativeWidgetGtk::OnMotionNotify(widget, event); -} - -void NativeWindowGtk::OnSizeAllocate(GtkWidget* widget, - GtkAllocation* allocation) { - NativeWidgetGtk::OnSizeAllocate(widget, allocation); - - // The Window's NonClientView may provide a custom shape for the Window. - gfx::Path window_mask; - GetWindow()->non_client_view()->GetWindowMask(gfx::Size(allocation->width, - allocation->height), - &window_mask); - GdkRegion* mask_region = window_mask.CreateNativeRegion(); - gdk_window_shape_combine_region(GetNativeView()->window, mask_region, 0, 0); - if (mask_region) - gdk_region_destroy(mask_region); - - SaveWindowPosition(); -} - -gboolean NativeWindowGtk::OnLeaveNotify(GtkWidget* widget, - GdkEventCrossing* event) { - gdk_window_set_cursor(widget->window, gfx::GetCursor(GDK_LEFT_PTR)); - - return NativeWidgetGtk::OnLeaveNotify(widget, event); -} - -void NativeWindowGtk::InitNativeWidget(const Widget::InitParams& params) { - NativeWidgetGtk::InitNativeWidget(params); - - g_signal_connect(G_OBJECT(GetNativeWindow()), "configure-event", - G_CALLBACK(CallConfigureEvent), this); -} - -//////////////////////////////////////////////////////////////////////////////// // NativeWindowGtk, NativeWindow implementation: NativeWidget* NativeWindowGtk::AsNativeWidget() { @@ -205,10 +36,6 @@ const NativeWidget* NativeWindowGtk::AsNativeWidget() const { return this; } -void NativeWindowGtk::BecomeModal() { - gtk_window_set_modal(GetNativeWindow(), true); -} - Window* NativeWindowGtk::GetWindow() { return delegate_->AsWindow(); } @@ -218,36 +45,8 @@ const Window* NativeWindowGtk::GetWindow() const { } //////////////////////////////////////////////////////////////////////////////// -// NativeWindowGtk, NativeWidgetGtk overrides: - -gboolean NativeWindowGtk::OnWindowStateEvent(GtkWidget* widget, - GdkEventWindowState* event) { - if (!(event->new_window_state & GDK_WINDOW_STATE_WITHDRAWN)) - SaveWindowPosition(); - return NativeWidgetGtk::OnWindowStateEvent(widget, event); -} - -//////////////////////////////////////////////////////////////////////////////// // NativeWindowGtk, private: -// static -gboolean NativeWindowGtk::CallConfigureEvent(GtkWidget* widget, - GdkEventConfigure* event, - NativeWindowGtk* window_gtk) { - return window_gtk->OnConfigureEvent(widget, event); -} - -void NativeWindowGtk::SaveWindowPosition() { - // The delegate may have gone away on us. - if (!GetWindow()->window_delegate()) - return; - - bool maximized = window_state_ & GDK_WINDOW_STATE_MAXIMIZED; - GetWindow()->window_delegate()->SaveWindowPlacement( - GetWidget()->GetWindowScreenBounds(), - maximized); -} - //////////////////////////////////////////////////////////////////////////////// // NativeWindow, public: diff --git a/views/window/native_window_gtk.h b/views/window/native_window_gtk.h index e3e5799..9988a23 100644 --- a/views/window/native_window_gtk.h +++ b/views/window/native_window_gtk.h @@ -9,21 +9,12 @@ #include "base/basictypes.h" #include "views/widget/native_widget_gtk.h" #include "views/window/native_window.h" -#include "views/window/window.h" - -namespace gfx { -class Point; -class Size; -}; namespace views { namespace internal { class NativeWindowDelegate; } -class Client; -class WindowDelegate; - // Window implementation for Gtk. class NativeWindowGtk : public NativeWidgetGtk, public NativeWindow { public: @@ -33,52 +24,18 @@ class NativeWindowGtk : public NativeWidgetGtk, public NativeWindow { virtual Window* GetWindow() OVERRIDE; virtual const Window* GetWindow() const OVERRIDE; - // Overridden from NativeWidgetGtk: - virtual gboolean OnButtonPress(GtkWidget* widget, GdkEventButton* event); - virtual gboolean OnConfigureEvent(GtkWidget* widget, - GdkEventConfigure* event); - virtual gboolean OnMotionNotify(GtkWidget* widget, GdkEventMotion* event); - virtual void OnSizeAllocate(GtkWidget* widget, GtkAllocation* allocation); - virtual gboolean OnLeaveNotify(GtkWidget* widget, GdkEventCrossing* event); - protected: - virtual void InitNativeWidget(const Widget::InitParams& params) OVERRIDE; - // Overridden from NativeWindow: virtual NativeWidget* AsNativeWidget() OVERRIDE; virtual const NativeWidget* AsNativeWidget() const OVERRIDE; - virtual void BecomeModal() OVERRIDE; - - // Overridden from NativeWidgetGtk: - virtual gboolean OnWindowStateEvent(GtkWidget* widget, - GdkEventWindowState* event) OVERRIDE; // For the constructor. friend class Window; private: - static gboolean CallConfigureEvent(GtkWidget* widget, - GdkEventConfigure* event, - NativeWindowGtk* window_gtk); - - // Asks the delegate if any to save the window's location and size. - void SaveWindowPosition(); - // A delegate implementation that handles events received here. internal::NativeWindowDelegate* delegate_; - // Our window delegate. - WindowDelegate* window_delegate_; - - // The View that provides the non-client area of the window (title bar, - // window controls, sizing borders etc). To use an implementation other than - // the default, this class must be subclassed and this value set to the - // desired implementation before calling |Init|. - NonClientView* non_client_view_; - - // Set to true if the window is in the process of closing. - bool window_closed_; - DISALLOW_COPY_AND_ASSIGN(NativeWindowGtk); }; diff --git a/views/window/native_window_win.cc b/views/window/native_window_win.cc index 611b6fe..a902d10 100644 --- a/views/window/native_window_win.cc +++ b/views/window/native_window_win.cc @@ -4,19 +4,12 @@ #include "views/window/native_window_win.h" -#include <dwmapi.h> -#include <shellapi.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 "ui/base/accessibility/accessibility_types.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 "ui/gfx/canvas_skia_paint.h" #include "ui/gfx/font.h" #include "ui/gfx/path.h" #include "views/accessibility/native_view_accessibility_win.h" @@ -26,48 +19,6 @@ #include "views/window/window_delegate.h" namespace views { -namespace { - -// 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, - gfx::Rect* work_area) { - DCHECK(monitor); - DCHECK(monitor_rect); - DCHECK(work_area); - *monitor = MonitorFromRect(&rect, MONITOR_DEFAULTTONULL); - if (!*monitor) - return false; - MONITORINFO monitor_info = { 0 }; - monitor_info.cbSize = sizeof(monitor_info); - GetMonitorInfo(*monitor, &monitor_info); - *monitor_rect = monitor_info.rcMonitor; - *work_area = monitor_info.rcWork; - return true; -} - -// 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); -} - -HWND GetOwner(HWND window) { - return ::GetWindow(window, GW_OWNER); -} - -} // namespace - namespace internal { void EnsureRectIsVisibleInRect(const gfx::Rect& parent_rect, @@ -114,12 +65,7 @@ void EnsureRectIsVisibleInRect(const gfx::Rect& parent_rect, NativeWindowWin::NativeWindowWin(internal::NativeWindowDelegate* delegate) : NativeWidgetWin(delegate->AsNativeWidgetDelegate()), - delegate_(delegate), - restored_enabled_(false), - ignore_window_pos_changes_(false), - ignore_pos_changes_factory_(this), - is_right_mouse_pressed_on_caption_(false), - last_monitor_(NULL) { + delegate_(delegate) { is_window_ = true; // Initialize these values to 0 so that subclasses can override the default // behavior before calling Init. @@ -130,367 +76,6 @@ NativeWindowWin::NativeWindowWin(internal::NativeWindowDelegate* delegate) NativeWindowWin::~NativeWindowWin() { } -// static -gfx::Font NativeWindowWin::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); -} - -/////////////////////////////////////////////////////////////////////////////// -// NativeWindowWin, NativeWidgetWin overrides: - -void NativeWindowWin::InitNativeWidget(const Widget::InitParams& params) { - if (window_style() == 0) - set_window_style(CalculateWindowStyle()); - if (window_ex_style() == 0) - set_window_ex_style(CalculateWindowExStyle()); - - GetMonitorAndRects(params.bounds.ToRECT(), &last_monitor_, - &last_monitor_rect_, &last_work_area_); - - NativeWidgetWin::InitNativeWidget(params); -} - -void NativeWindowWin::OnDestroy() { - RestoreEnabledIfNecessary(); - NativeWidgetWin::OnDestroy(); -} - -LRESULT NativeWindowWin::OnMouseRange(UINT message, - WPARAM w_param, - LPARAM l_param) { - if (message == WM_RBUTTONUP && is_right_mouse_pressed_on_caption_) { - is_right_mouse_pressed_on_caption_ = false; - ReleaseCapture(); - // |point| is in window coordinates, but WM_NCHITTEST and TrackPopupMenu() - // expect screen coordinates. - CPoint screen_point(l_param); - MapWindowPoints(GetNativeView(), HWND_DESKTOP, &screen_point, 1); - w_param = SendMessage(GetNativeView(), WM_NCHITTEST, 0, - MAKELPARAM(screen_point.x, screen_point.y)); - if (w_param == HTCAPTION || w_param == HTSYSMENU) { - UINT flags = TPM_LEFTBUTTON | TPM_RIGHTBUTTON | TPM_RETURNCMD; - if (base::i18n::IsRTL()) - flags |= TPM_RIGHTALIGN; - HMENU system_menu = GetSystemMenu(GetNativeView(), FALSE); - int id = TrackPopupMenu(system_menu, flags, screen_point.x, - screen_point.y, 0, GetNativeView(), NULL); - ExecuteSystemMenuCommand(id); - return 0; - } - } else if (message == WM_NCLBUTTONDOWN && - !GetWindow()->ShouldUseNativeFrame()) { - switch (w_param) { - case HTCLOSE: - case HTMINBUTTON: - case HTMAXBUTTON: { - // When the mouse is pressed down in these specific non-client areas, - // we need to tell the RootView to send the mouse pressed event (which - // sets capture, allowing subsequent WM_LBUTTONUP (note, _not_ - // WM_NCLBUTTONUP) to fire so that the appropriate WM_SYSCOMMAND can be - // sent by the applicable button's ButtonListener. We _have_ to do this - // way rather than letting Windows just send the syscommand itself (as - // would happen if we never did this dance) because for some insane - // reason DefWindowProc for WM_NCLBUTTONDOWN also renders the pressed - // window control button appearance, in the Windows classic style, over - // our view! Ick! By handling this message we prevent Windows from - // doing this undesirable thing, but that means we need to roll the - // sys-command handling ourselves. - // Combine |w_param| with common key state message flags. - w_param |= ((GetKeyState(VK_CONTROL) & 0x80) == 0x80)? MK_CONTROL : 0; - w_param |= ((GetKeyState(VK_SHIFT) & 0x80) == 0x80)? MK_SHIFT : 0; - } - } - } else if (message == WM_NCRBUTTONDOWN && - (w_param == HTCAPTION || w_param == HTSYSMENU)) { - is_right_mouse_pressed_on_caption_ = true; - // We SetMouseCapture() to ensure we only show the menu when the button - // down and up are both on the caption. Note: this causes the button up to - // be WM_RBUTTONUP instead of WM_NCRBUTTONUP. - SetMouseCapture(); - } - - /* - TODO(beng): This fixes some situations where the windows-classic appearance - non-client area is rendered over our custom frame, however it - causes mouse-releases to the non-client area to be eaten, so it - can't be enabled. - if (message == WM_NCLBUTTONDOWN) { - // NativeWindowWin::OnNCLButtonDown set the message as un-handled. This - // normally means NativeWidgetWin::ProcessWindowMessage will pass it to - // DefWindowProc. Sadly, DefWindowProc for WM_NCLBUTTONDOWN does weird - // non-client painting, so we need to call it directly here inside a - // scoped update lock. - ScopedRedrawLock lock(this); - NativeWidgetWin::OnMouseRange(message, w_param, l_param); - DefWindowProc(GetNativeView(), WM_NCLBUTTONDOWN, w_param, l_param); - SetMsgHandled(TRUE); - } - */ - - NativeWidgetWin::OnMouseRange(message, w_param, l_param); - return 0; -} - -LRESULT NativeWindowWin::OnNCCalcSize(BOOL mode, LPARAM l_param) { - // We only override the default handling if we need to specify a custom - // non-client edge width. Note that in most cases "no insets" means no - // custom width, but in fullscreen mode we want a custom width of 0. - gfx::Insets insets = GetClientAreaInsets(); - if (insets.empty() && !IsFullscreen()) - return NativeWidgetWin::OnNCCalcSize(mode, l_param); - - RECT* client_rect = mode ? - &reinterpret_cast<NCCALCSIZE_PARAMS*>(l_param)->rgrc[0] : - reinterpret_cast<RECT*>(l_param); - client_rect->left += insets.left(); - client_rect->top += insets.top(); - client_rect->bottom -= insets.bottom(); - client_rect->right -= insets.right(); - if (IsMaximized()) { - // Find all auto-hide taskbars along the screen edges and adjust in by the - // thickness of the auto-hide taskbar on each such edge, so the window isn't - // treated as a "fullscreen app", which would cause the taskbars to - // disappear. - HMONITOR monitor = MonitorFromWindow(GetNativeView(), - MONITOR_DEFAULTTONULL); - if (!monitor) { - // We might end up here if the window was previously minimized and the - // user clicks on the taskbar button to restore it in the previously - // maximized position. In that case WM_NCCALCSIZE is sent before the - // window coordinates are restored to their previous values, so our - // (left,top) would probably be (-32000,-32000) like all minimized - // windows. So the above MonitorFromWindow call fails, but if we check - // the window rect given with WM_NCCALCSIZE (which is our previous - // restored window position) we will get the correct monitor handle. - monitor = MonitorFromRect(client_rect, MONITOR_DEFAULTTONULL); - if (!monitor) { - // This is probably an extreme case that we won't hit, but if we don't - // intersect any monitor, let us not adjust the client rect since our - // window will not be visible anyway. - return 0; - } - } - if (EdgeHasTopmostAutoHideTaskbar(ABE_LEFT, monitor)) - client_rect->left += kAutoHideTaskbarThicknessPx; - if (EdgeHasTopmostAutoHideTaskbar(ABE_TOP, monitor)) { - if (GetWindow()->ShouldUseNativeFrame()) { - // Tricky bit. Due to a bug in DwmDefWindowProc()'s handling of - // WM_NCHITTEST, having any nonclient area atop the window causes the - // caption buttons to draw onscreen but not respond to mouse - // hover/clicks. - // So for a taskbar at the screen top, we can't push the - // client_rect->top down; instead, we move the bottom up by one pixel, - // which is the smallest change we can make and still get a client area - // less than the screen size. This is visibly ugly, but there seems to - // be no better solution. - --client_rect->bottom; - } else { - client_rect->top += 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 - // the width/height of the upper-left nonclient area. - return 0; - } - - // If the window bounds change, we're going to relayout and repaint anyway. - // Returning WVR_REDRAW avoids an extra paint before that of the old client - // pixels in the (now wrong) location, and thus makes actions like resizing a - // window from the left edge look slightly less broken. - // We special case when left or top insets are 0, since these conditions - // actually require another repaint to correct the layout after glass gets - // turned on and off. - if (insets.left() == 0 || insets.top() == 0) - return 0; - return mode ? WVR_REDRAW : 0; -} - -namespace { -struct ClipState { - // The window being painted. - HWND parent; - - // DC painting to. - HDC dc; - - // Origin of the window in terms of the screen. - int x; - int y; -}; - -// See comments in OnNCPaint for details of this function. -static BOOL CALLBACK ClipDCToChild(HWND window, LPARAM param) { - ClipState* clip_state = reinterpret_cast<ClipState*>(param); - if (GetParent(window) == clip_state->parent && IsWindowVisible(window)) { - RECT bounds; - GetWindowRect(window, &bounds); - ExcludeClipRect(clip_state->dc, - bounds.left - clip_state->x, - bounds.top - clip_state->y, - bounds.right - clip_state->x, - bounds.bottom - clip_state->y); - } - return TRUE; -} -} // namespace - -void NativeWindowWin::OnNCPaint(HRGN rgn) { - // We only do non-client painting if we're not using the native frame. - // It's required to avoid some native painting artifacts from appearing when - // the window is resized. - if (GetWindow()->ShouldUseNativeFrame()) { - NativeWidgetWin::OnNCPaint(rgn); - return; - } - - // We have an NC region and need to paint it. We expand the NC region to - // include the dirty region of the root view. This is done to minimize - // paints. - CRect window_rect; - GetWindowRect(&window_rect); - - if (window_rect.Width() != GetWidget()->GetRootView()->width() || - window_rect.Height() != GetWidget()->GetRootView()->height()) { - // If the size of the window differs from the size of the root view it - // means we're being asked to paint before we've gotten a WM_SIZE. This can - // happen when the user is interactively resizing the window. To avoid - // mass flickering we don't do anything here. Once we get the WM_SIZE we'll - // reset the region of the window which triggers another WM_NCPAINT and - // all is well. - return; - } - - CRect dirty_region; - // A value of 1 indicates paint all. - if (!rgn || rgn == reinterpret_cast<HRGN>(1)) { - dirty_region = CRect(0, 0, window_rect.Width(), window_rect.Height()); - } else { - RECT rgn_bounding_box; - GetRgnBox(rgn, &rgn_bounding_box); - if (!IntersectRect(&dirty_region, &rgn_bounding_box, &window_rect)) - return; // Dirty region doesn't intersect window bounds, bale. - - // rgn_bounding_box is in screen coordinates. Map it to window coordinates. - OffsetRect(&dirty_region, -window_rect.left, -window_rect.top); - } - - // In theory GetDCEx should do what we want, but I couldn't get it to work. - // In particular the docs mentiond DCX_CLIPCHILDREN, but as far as I can tell - // it doesn't work at all. So, instead we get the DC for the window then - // manually clip out the children. - HDC dc = GetWindowDC(GetNativeView()); - ClipState clip_state; - clip_state.x = window_rect.left; - clip_state.y = window_rect.top; - clip_state.parent = GetNativeView(); - clip_state.dc = dc; - EnumChildWindows(GetNativeView(), &ClipDCToChild, - reinterpret_cast<LPARAM>(&clip_state)); - - gfx::Rect old_paint_region = invalid_rect(); - - if (!old_paint_region.IsEmpty()) { - // The root view has a region that needs to be painted. Include it in the - // region we're going to paint. - - CRect old_paint_region_crect = old_paint_region.ToRECT(); - CRect tmp = dirty_region; - UnionRect(&dirty_region, &tmp, &old_paint_region_crect); - } - - GetWidget()->GetRootView()->SchedulePaintInRect(gfx::Rect(dirty_region)); - - // gfx::CanvasSkiaPaint's destructor does the actual painting. As such, wrap - // the following in a block to force paint to occur so that we can release - // the dc. - { - gfx::CanvasSkiaPaint canvas(dc, true, dirty_region.left, - dirty_region.top, dirty_region.Width(), - dirty_region.Height()); - delegate_->AsNativeWidgetDelegate()->OnNativeWidgetPaint(&canvas); - } - - ReleaseDC(GetNativeView(), dc); - // When using a custom frame, we want to avoid calling DefWindowProc() since - // that may render artifacts. - SetMsgHandled(!GetWindow()->ShouldUseNativeFrame()); -} - -void NativeWindowWin::OnWindowPosChanging(WINDOWPOS* window_pos) { - if (ignore_window_pos_changes_) { - // If somebody's trying to toggle our visibility, change the nonclient area, - // change our Z-order, or activate us, we should probably let it go through. - if (!(window_pos->flags & ((IsVisible() ? SWP_HIDEWINDOW : SWP_SHOWWINDOW) | - SWP_FRAMECHANGED)) && - (window_pos->flags & (SWP_NOZORDER | SWP_NOACTIVATE))) { - // Just sizing/moving the window; ignore. - window_pos->flags |= SWP_NOSIZE | SWP_NOMOVE | SWP_NOREDRAW; - window_pos->flags &= ~(SWP_SHOWWINDOW | SWP_HIDEWINDOW); - } - } else if (!GetParent()) { - CRect window_rect; - HMONITOR monitor; - gfx::Rect monitor_rect, work_area; - if (GetWindowRect(&window_rect) && - GetMonitorAndRects(window_rect, &monitor, &monitor_rect, &work_area)) { - if (monitor && (monitor == last_monitor_) && - (IsFullscreen() || ((monitor_rect == last_monitor_rect_) && - (work_area != last_work_area_)))) { - // A rect for the monitor we're on changed. Normally Windows notifies - // us about this (and thus we're reaching here due to the SetWindowPos() - // call in OnSettingChange() above), but with some software (e.g. - // nVidia's nView desktop manager) the work area can change asynchronous - // to any notification, and we're just sent a SetWindowPos() call with a - // new (frequently incorrect) position/size. In either case, the best - // response is to throw away the existing position/size information in - // |window_pos| and recalculate it based on the new work rect. - gfx::Rect new_window_rect; - if (IsFullscreen()) { - new_window_rect = monitor_rect; - } else if (IsZoomed()) { - new_window_rect = work_area; - int border_thickness = GetSystemMetrics(SM_CXSIZEFRAME); - new_window_rect.Inset(-border_thickness, -border_thickness); - } else { - new_window_rect = gfx::Rect(window_rect).AdjustToFit(work_area); - } - window_pos->x = new_window_rect.x(); - window_pos->y = new_window_rect.y(); - window_pos->cx = new_window_rect.width(); - window_pos->cy = new_window_rect.height(); - // WARNING! Don't set SWP_FRAMECHANGED here, it breaks moving the child - // HWNDs for some reason. - window_pos->flags &= ~(SWP_NOSIZE | SWP_NOMOVE | SWP_NOREDRAW); - window_pos->flags |= SWP_NOCOPYBITS; - - // Now ignore all immediately-following SetWindowPos() changes. Windows - // likes to (incorrectly) recalculate what our position/size should be - // and send us further updates. - ignore_window_pos_changes_ = true; - DCHECK(ignore_pos_changes_factory_.empty()); - MessageLoop::current()->PostTask(FROM_HERE, - ignore_pos_changes_factory_.NewRunnableMethod( - &NativeWindowWin::StopIgnoringPosChanges)); - } - last_monitor_ = monitor; - last_monitor_rect_ = monitor_rect; - last_work_area_ = work_area; - } - } - - NativeWidgetWin::OnWindowPosChanging(window_pos); -} - //////////////////////////////////////////////////////////////////////////////// // NativeWindowWin, NativeWindow implementation: @@ -510,58 +95,6 @@ const NativeWidget* NativeWindowWin::AsNativeWidget() const { return this; } -void NativeWindowWin::BecomeModal() { - // We implement modality by crawling up the hierarchy of windows starting - // at the owner, disabling all of them so that they don't receive input - // messages. - HWND start = GetOwner(GetNativeView()); - while (start) { - ::EnableWindow(start, FALSE); - start = ::GetParent(start); - } -} - -//////////////////////////////////////////////////////////////////////////////// -// NativeWindowWin, private: - -void NativeWindowWin::RestoreEnabledIfNecessary() { - if (delegate_->IsModal() && !restored_enabled_) { - restored_enabled_ = true; - // If we were run modally, we need to undo the disabled-ness we inflicted on - // the owner's parent hierarchy. - HWND start = GetOwner(GetNativeView()); - while (start) { - ::EnableWindow(start, TRUE); - start = ::GetParent(start); - } - } -} - -DWORD NativeWindowWin::CalculateWindowStyle() { - DWORD window_styles = - WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_SYSMENU | WS_CAPTION; - bool can_resize = GetWindow()->window_delegate()->CanResize(); - bool can_maximize = GetWindow()->window_delegate()->CanMaximize(); - if (can_maximize) { - window_styles |= WS_OVERLAPPEDWINDOW; - } else if (can_resize) { - window_styles |= WS_OVERLAPPED | WS_THICKFRAME; - } - if (delegate_->IsDialogBox()) { - window_styles |= DS_MODALFRAME; - // NOTE: Turning this off means we lose the close button, which is bad. - // Turning it on though means the user can maximize or size the window - // from the system menu, which is worse. We may need to provide our own - // menu to get the close button to appear properly. - // window_styles &= ~WS_SYSMENU; - } - return window_styles; -} - -DWORD NativeWindowWin::CalculateWindowExStyle() { - return delegate_->IsDialogBox() ? WS_EX_DLGMODALFRAME : 0; -} - //////////////////////////////////////////////////////////////////////////////// // NativeWindow, public: diff --git a/views/window/native_window_win.h b/views/window/native_window_win.h index 3243739..956a3ac 100644 --- a/views/window/native_window_win.h +++ b/views/window/native_window_win.h @@ -8,13 +8,6 @@ #include "views/widget/native_widget_win.h" #include "views/window/native_window.h" -#include "views/window/window.h" - -namespace gfx { -class Font; -class Point; -class Size; -}; namespace views { namespace internal { @@ -29,9 +22,6 @@ void EnsureRectIsVisibleInRect(const gfx::Rect& parent_rect, } // namespace internal -class Client; -class WindowDelegate; - //////////////////////////////////////////////////////////////////////////////// // // NativeWindowWin @@ -47,9 +37,6 @@ class NativeWindowWin : public NativeWidgetWin, explicit NativeWindowWin(internal::NativeWindowDelegate* delegate); virtual ~NativeWindowWin(); - // Returns the system set window title font. - static gfx::Font GetWindowTitleFont(); - // Overridden from NativeWindow: virtual Window* GetWindow() OVERRIDE; virtual const Window* GetWindow() const OVERRIDE; @@ -57,62 +44,14 @@ class NativeWindowWin : public NativeWidgetWin, protected: friend Window; - // Overridden from NativeWidgetWin: - virtual void InitNativeWidget(const Widget::InitParams& params) OVERRIDE; - virtual void OnDestroy() OVERRIDE; - virtual LRESULT OnMouseRange(UINT message, - WPARAM w_param, - LPARAM l_param) OVERRIDE; - LRESULT OnNCCalcSize(BOOL mode, LPARAM l_param); // Don't override. - virtual void OnNCPaint(HRGN rgn) OVERRIDE; - virtual void OnWindowPosChanging(WINDOWPOS* window_pos) OVERRIDE; - // Overridden from NativeWindow: virtual NativeWidget* AsNativeWidget() OVERRIDE; virtual const NativeWidget* AsNativeWidget() const OVERRIDE; - virtual void BecomeModal() OVERRIDE; private: - // If necessary, enables all ancestors. - void RestoreEnabledIfNecessary(); - - // Calculate the appropriate window styles for this window. - DWORD CalculateWindowStyle(); - DWORD CalculateWindowExStyle(); - - // Stops ignoring SetWindowPos() requests (see below). - void StopIgnoringPosChanges() { ignore_window_pos_changes_ = false; } - - // Update accessibility information via our WindowDelegate. - void UpdateAccessibleName(std::wstring& accessible_name); - void UpdateAccessibleRole(); - void UpdateAccessibleState(); - // A delegate implementation that handles events received here. internal::NativeWindowDelegate* delegate_; - // Whether all ancestors have been enabled. This is only used if is_modal_ is - // true. - bool restored_enabled_; - - // When true, this flag makes us discard incoming SetWindowPos() requests that - // only change our position/size. (We still allow changes to Z-order, - // activation, etc.) - bool ignore_window_pos_changes_; - - // The following factory is used to ignore SetWindowPos() calls for short time - // periods. - ScopedRunnableMethodFactory<NativeWindowWin> ignore_pos_changes_factory_; - - // Set to true when the user presses the right mouse button on the caption - // area. We need this so we can correctly show the context menu on mouse-up. - bool is_right_mouse_pressed_on_caption_; - - // The last-seen monitor containing us, and its rect and work area. These are - // used to catch updates to the rect and work area and react accordingly. - HMONITOR last_monitor_; - gfx::Rect last_monitor_rect_, last_work_area_; - DISALLOW_COPY_AND_ASSIGN(NativeWindowWin); }; diff --git a/views/window/window.cc b/views/window/window.cc index d16ff6c..ecfaa57 100644 --- a/views/window/window.cc +++ b/views/window/window.cc @@ -6,8 +6,6 @@ #include "base/string_util.h" #include "third_party/skia/include/core/SkBitmap.h" -#include "ui/base/l10n/l10n_font_util.h" -#include "ui/base/resource/resource_bundle.h" #include "ui/gfx/font.h" #include "ui/gfx/rect.h" #include "ui/gfx/size.h" @@ -29,9 +27,7 @@ Window::InitParams::InitParams(WindowDelegate* window_delegate) } Window::Window() - : native_window_(NULL), - saved_maximized_state_(false), - minimum_size_(100, 100) { + : native_window_(NULL) { } Window::~Window() { @@ -52,25 +48,6 @@ Window* Window::CreateChromeWindow(gfx::NativeWindow parent, return window; } -// static -int Window::GetLocalizedContentsWidth(int col_resource_id) { - return ui::GetLocalizedContentsWidthForFont(col_resource_id, - ResourceBundle::GetSharedInstance().GetFont(ResourceBundle::BaseFont)); -} - -// static -int Window::GetLocalizedContentsHeight(int row_resource_id) { - return ui::GetLocalizedContentsHeightForFont(row_resource_id, - ResourceBundle::GetSharedInstance().GetFont(ResourceBundle::BaseFont)); -} - -// static -gfx::Size Window::GetLocalizedContentsSize(int col_resource_id, - int row_resource_id) { - return gfx::Size(GetLocalizedContentsWidth(col_resource_id), - GetLocalizedContentsHeight(row_resource_id)); -} - void Window::InitWindow(const InitParams& params) { native_window_ = params.native_window ? params.native_window @@ -82,22 +59,11 @@ void Window::InitWindow(const InitParams& params) { modified_params.widget_init_params.native_widget = native_window_->AsNativeWidget(); Init(modified_params.widget_init_params); - OnNativeWindowCreated(modified_params.widget_init_params.bounds); } //////////////////////////////////////////////////////////////////////////////// // Window, Widget overrides: -void Window::Show() { - native_window_->AsNativeWidget()->ShowNativeWidget( - saved_maximized_state_ ? NativeWidget::SHOW_MAXIMIZED - : NativeWidget::SHOW_RESTORED); - // |saved_maximized_state_| only applies the first time the window is shown. - // If we don't reset the value the window will be shown maximized every time - // it is subsequently shown after being hidden. - saved_maximized_state_ = false; -} - Window* Window::AsWindow() { return this; } @@ -109,75 +75,8 @@ const Window* Window::AsWindow() const { //////////////////////////////////////////////////////////////////////////////// // Window, internal::NativeWindowDelegate implementation: -bool Window::IsModal() const { - return widget_delegate()->IsModal(); -} - -bool Window::IsDialogBox() const { - return !!widget_delegate()->AsDialogDelegate(); -} - -void Window::OnNativeWindowCreated(const gfx::Rect& bounds) { - if (widget_delegate()->IsModal()) - native_window_->BecomeModal(); - - UpdateWindowTitle(); - SetInitialBounds(bounds); -} - internal::NativeWidgetDelegate* Window::AsNativeWidgetDelegate() { return this; } -//////////////////////////////////////////////////////////////////////////////// -// Window, private: - -void Window::SetInitialBounds(const gfx::Rect& bounds) { - // First we obtain the window's saved show-style and store it. We need to do - // this here, rather than in Show() because by the time Show() is called, - // the window's size will have been reset (below) and the saved maximized - // state will have been lost. Sadly there's no way to tell on Windows when - // a window is restored from maximized state, so we can't more accurately - // track maximized state independently of sizing information. - widget_delegate()->GetSavedMaximizedState( - &saved_maximized_state_); - - // Restore the window's placement from the controller. - gfx::Rect saved_bounds = bounds; - if (widget_delegate()->GetSavedWindowBounds(&saved_bounds)) { - if (!widget_delegate()->ShouldRestoreWindowSize()) { - saved_bounds.set_size(non_client_view()->GetPreferredSize()); - } else { - // Make sure the bounds are at least the minimum size. - if (saved_bounds.width() < minimum_size_.width()) { - saved_bounds.SetRect(saved_bounds.x(), saved_bounds.y(), - saved_bounds.right() + minimum_size_.width() - - saved_bounds.width(), - saved_bounds.bottom()); - } - - if (saved_bounds.height() < minimum_size_.height()) { - saved_bounds.SetRect(saved_bounds.x(), saved_bounds.y(), - saved_bounds.right(), - saved_bounds.bottom() + minimum_size_.height() - - saved_bounds.height()); - } - } - - // Widget's SetBounds method does not further modify the bounds that are - // passed to it. - SetBounds(saved_bounds); - } else { - if (bounds.IsEmpty()) { - // No initial bounds supplied, so size the window to its content and - // center over its parent. - native_window_->AsNativeWidget()->CenterWindow( - non_client_view()->GetPreferredSize()); - } else { - // Use the supplied initial bounds. - SetBoundsConstrained(bounds, NULL); - } - } -} - } // namespace views diff --git a/views/window/window.h b/views/window/window.h index 4fb8321..e3a36d5 100644 --- a/views/window/window.h +++ b/views/window/window.h @@ -11,7 +11,6 @@ #include "views/window/native_window_delegate.h" namespace gfx { -class Font; class Rect; class Size; } // namespace gfx @@ -50,22 +49,11 @@ class Window : public Widget, const gfx::Rect& bounds, WindowDelegate* window_delegate); - // Returns the preferred size of the contents view of this window based on - // its localized size data. The width in cols is held in a localized string - // resource identified by |col_resource_id|, the height in the same fashion. - // TODO(beng): This should eventually live somewhere else, probably closer to - // ClientView. - static int GetLocalizedContentsWidth(int col_resource_id); - static int GetLocalizedContentsHeight(int row_resource_id); - static gfx::Size GetLocalizedContentsSize(int col_resource_id, - int row_resource_id); - // Initializes the window. Must be called before any post-configuration // operations are performed. void InitWindow(const InitParams& params); // Overridden from Widget: - virtual void Show() OVERRIDE; virtual Window* AsWindow() OVERRIDE; virtual const Window* AsWindow() const OVERRIDE; @@ -81,24 +69,11 @@ class Window : public Widget, protected: // Overridden from NativeWindowDelegate: - virtual bool IsModal() const OVERRIDE; - virtual bool IsDialogBox() const OVERRIDE; - virtual void OnNativeWindowCreated(const gfx::Rect& bounds) OVERRIDE; virtual internal::NativeWidgetDelegate* AsNativeWidgetDelegate() OVERRIDE; private: - // Sizes and positions the window just after it is created. - void SetInitialBounds(const gfx::Rect& bounds); - NativeWindow* native_window_; - // The saved maximized state for this window. See note in SetInitialBounds - // that explains why we save this. - bool saved_maximized_state_; - - // The smallest size the window can be. - gfx::Size minimum_size_; - DISALLOW_COPY_AND_ASSIGN(Window); }; |