summaryrefslogtreecommitdiffstats
path: root/ui/views/widget/native_widget_win.cc
diff options
context:
space:
mode:
Diffstat (limited to 'ui/views/widget/native_widget_win.cc')
-rw-r--r--ui/views/widget/native_widget_win.cc328
1 files changed, 110 insertions, 218 deletions
diff --git a/ui/views/widget/native_widget_win.cc b/ui/views/widget/native_widget_win.cc
index 15e8d2c..be19bd1 100644
--- a/ui/views/widget/native_widget_win.cc
+++ b/ui/views/widget/native_widget_win.cc
@@ -238,30 +238,12 @@ BOOL CALLBACK SendDwmCompositionChanged(HWND window, LPARAM param) {
return TRUE;
}
-// Tells the window its frame (non-client area) has changed.
-void SendFrameChanged(HWND window) {
- SetWindowPos(window, NULL, 0, 0, 0, 0,
- SWP_FRAMECHANGED | SWP_NOACTIVATE | SWP_NOCOPYBITS |
- SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_NOREPOSITION |
- SWP_NOSENDCHANGING | SWP_NOSIZE | SWP_NOZORDER);
-}
-
// Enables or disables the menu item for the specified command and menu.
void EnableMenuItem(HMENU menu, UINT command, bool enabled) {
UINT flags = MF_BYCOMMAND | (enabled ? MF_ENABLED : MF_DISABLED | MF_GRAYED);
EnableMenuItem(menu, command, flags);
}
-BOOL CALLBACK EnumChildWindowsForRedraw(HWND hwnd, LPARAM lparam) {
- DWORD process_id;
- GetWindowThreadProcessId(hwnd, &process_id);
- int flags = RDW_INVALIDATE | RDW_NOCHILDREN | RDW_FRAME;
- if (process_id == GetCurrentProcessId())
- flags |= RDW_UPDATENOW;
- RedrawWindow(hwnd, NULL, NULL, flags);
- return TRUE;
-}
-
// See comments in OnNCPaint() for details of this struct.
struct ClipState {
// The window being painted.
@@ -314,10 +296,6 @@ bool GetMonitorAndRects(const RECT& rect,
// Links the HWND to its NativeWidget.
const char* const kNativeWidgetKey = "__VIEWS_NATIVE_WIDGET__";
-// A custom MSAA object id used to determine if a screen reader is actively
-// listening for MSAA events.
-const int kCustomObjectID = 1;
-
const int kDragFrameWindowAlpha = 200;
struct FindOwnedWindowsData {
@@ -568,7 +546,7 @@ void NativeWidgetWin::FrameTypeChanged() {
// Send a frame change notification, since the non-client metrics have
// changed.
- SendFrameChanged(GetNativeView());
+ message_handler_->SendFrameChanged();
// Update the non-client view with the correct frame view for the active frame
// type.
@@ -940,7 +918,7 @@ void NativeWidgetWin::ShowWithWindowState(ui::WindowShowState show_state) {
}
bool NativeWidgetWin::IsVisible() const {
- return !!::IsWindowVisible(hwnd());
+ return message_handler_->IsVisible();
}
void NativeWidgetWin::Activate() {
@@ -958,7 +936,7 @@ void NativeWidgetWin::Deactivate() {
}
bool NativeWidgetWin::IsActive() const {
- return GetActiveWindow() == hwnd();
+ return message_handler_->IsActive();
}
void NativeWidgetWin::SetAlwaysOnTop(bool on_top) {
@@ -1292,70 +1270,7 @@ void NativeWidgetWin::OnCommand(UINT notification_code,
}
LRESULT NativeWidgetWin::OnCreate(CREATESTRUCT* create_struct) {
- SetNativeWindowProperty(kNativeWidgetKey, this);
- CHECK_EQ(this, GetNativeWidgetForNativeView(hwnd()));
-
- use_layered_buffer_ = !!(window_ex_style() & WS_EX_LAYERED);
-
- // Attempt to detect screen readers by sending an event with our custom id.
- if (!IsAccessibleWidget())
- NotifyWinEvent(EVENT_SYSTEM_ALERT, hwnd(), kCustomObjectID, CHILDID_SELF);
-
- props_.push_back(ui::SetWindowSupportsRerouteMouseWheel(hwnd()));
-
- drop_target_ = new DropTargetWin(
- static_cast<internal::RootView*>(GetWidget()->GetRootView()));
-
- // We need to add ourselves as a message loop observer so that we can repaint
- // aggressively if the contents of our window become invalid. Unfortunately
- // WM_PAINT messages are starved and we get flickery redrawing when resizing
- // if we do not do this.
- MessageLoopForUI::current()->AddObserver(this);
-
- // Windows special DWM window frame requires a special tooltip manager so
- // that window controls in Chrome windows don't flicker when you move your
- // mouse over them. See comment in aero_tooltip_manager.h.
- Widget* widget = GetWidget()->GetTopLevelWidget();
- if (widget && widget->ShouldUseNativeFrame()) {
- tooltip_manager_.reset(new AeroTooltipManager(GetWidget()));
- } else {
- tooltip_manager_.reset(new TooltipManagerWin(GetWidget()));
- }
- if (!tooltip_manager_->Init()) {
- // There was a problem creating the TooltipManager. Common error is 127.
- // See 82193 for details.
- LOG_GETLASTERROR(WARNING) << "tooltip creation failed, disabling tooltips";
- tooltip_manager_.reset();
- }
-
- // This message initializes the window so that focus border are shown for
- // windows.
- SendMessage(
- hwnd(), WM_CHANGEUISTATE, MAKELPARAM(UIS_CLEAR, UISF_HIDEFOCUS), 0);
-
- // Bug 964884: detach the IME attached to this window.
- // We should attach IMEs only when we need to input CJK strings.
- ImmAssociateContextEx(hwnd(), NULL, 0);
-
- if (message_handler_->remove_standard_frame()) {
- SetWindowLong(GWL_STYLE, GetWindowLong(GWL_STYLE) & ~WS_CAPTION);
- SendFrameChanged(GetNativeView());
- }
-
- // We need to allow the delegate to size its contents since the window may not
- // receive a size notification when its initial bounds are specified at window
- // creation time.
- ClientAreaSizeChanged();
-
- delegate_->OnNativeWidgetCreated();
-
- // Get access to a modifiable copy of the system menu.
- GetSystemMenu(hwnd(), false);
-
- if (base::win::GetVersion() >= base::win::VERSION_WIN7)
- RegisterTouchWindow(hwnd(), 0);
-
- return 0;
+ return message_handler_->OnCreate(create_struct);
}
void NativeWidgetWin::OnDestroy() {
@@ -1369,8 +1284,7 @@ void NativeWidgetWin::OnDisplayChange(UINT bits_per_pixel, CSize screen_size) {
LRESULT NativeWidgetWin::OnDwmCompositionChanged(UINT msg,
WPARAM w_param,
LPARAM l_param) {
- message_handler_->OnDwmCompositionChanged(msg, w_param, l_param);
- return 0;
+ return message_handler_->OnDwmCompositionChanged(msg, w_param, l_param);
}
void NativeWidgetWin::OnEndSession(BOOL ending, UINT logoff) {
@@ -1393,65 +1307,20 @@ void NativeWidgetWin::OnExitSizeMove() {
message_handler_->OnExitSizeMove();
}
-LRESULT NativeWidgetWin::OnGetObject(UINT uMsg,
+LRESULT NativeWidgetWin::OnGetObject(UINT message,
WPARAM w_param,
LPARAM l_param) {
- LRESULT reference_result = static_cast<LRESULT>(0L);
-
- // Accessibility readers will send an OBJID_CLIENT message
- if (OBJID_CLIENT == l_param) {
- // Retrieve MSAA dispatch object for the root view.
- base::win::ScopedComPtr<IAccessible> root(
- GetWidget()->GetRootView()->GetNativeViewAccessible());
-
- // Create a reference that MSAA will marshall to the client.
- reference_result = LresultFromObject(IID_IAccessible, w_param,
- static_cast<IAccessible*>(root.Detach()));
- }
-
- if (kCustomObjectID == l_param) {
- // An MSAA client requestes our custom id. Assume that we have detected an
- // active windows screen reader.
- OnScreenReaderDetected();
-
- // Return with failure.
- return static_cast<LRESULT>(0L);
- }
-
- return reference_result;
+ return message_handler_->OnGetObject(message, w_param, l_param);
}
void NativeWidgetWin::OnGetMinMaxInfo(MINMAXINFO* minmax_info) {
- gfx::Size min_window_size(delegate_->GetMinimumSize());
- gfx::Size max_window_size(delegate_->GetMaximumSize());
- // Add the native frame border size to the minimum and maximum size if the
- // view reports its size as the client size.
- if (WidgetSizeIsClientSize()) {
- CRect client_rect, window_rect;
- GetClientRect(&client_rect);
- GetWindowRect(&window_rect);
- window_rect -= client_rect;
- min_window_size.Enlarge(window_rect.Width(), window_rect.Height());
- if (!max_window_size.IsEmpty())
- max_window_size.Enlarge(window_rect.Width(), window_rect.Height());
- }
- minmax_info->ptMinTrackSize.x = min_window_size.width();
- minmax_info->ptMinTrackSize.y = min_window_size.height();
- if (max_window_size.width() || max_window_size.height()) {
- if (!max_window_size.width())
- max_window_size.set_width(GetSystemMetrics(SM_CXMAXTRACK));
- if (!max_window_size.height())
- max_window_size.set_height(GetSystemMetrics(SM_CYMAXTRACK));
- minmax_info->ptMaxTrackSize.x = max_window_size.width();
- minmax_info->ptMaxTrackSize.y = max_window_size.height();
- }
- SetMsgHandled(FALSE);
+ message_handler_->OnGetMinMaxInfo(minmax_info);
}
void NativeWidgetWin::OnHScroll(int scroll_type,
short position,
HWND scrollbar) {
- SetMsgHandled(FALSE);
+ message_handler_->OnHScroll(scroll_type, position, scrollbar);
}
LRESULT NativeWidgetWin::OnImeMessages(UINT message,
@@ -1488,14 +1357,7 @@ void NativeWidgetWin::OnKillFocus(HWND focused_window) {
LRESULT NativeWidgetWin::OnMouseActivate(UINT message,
WPARAM w_param,
LPARAM l_param) {
- // TODO(beng): resolve this with the GetWindowLong() check on the subsequent
- // line.
- if (GetWidget()->non_client_view())
- return delegate_->CanActivate() ? MA_ACTIVATE : MA_NOACTIVATEANDEAT;
- if (GetWindowLong(GWL_EXSTYLE) & WS_EX_NOACTIVATE)
- return MA_NOACTIVATE;
- SetMsgHandled(FALSE);
- return MA_ACTIVATE;
+ return message_handler_->OnMouseActivate(message, w_param, l_param);
}
LRESULT NativeWidgetWin::OnMouseRange(UINT message,
@@ -1598,50 +1460,7 @@ void NativeWidgetWin::OnMoving(UINT param, const LPRECT new_bounds) {
}
LRESULT NativeWidgetWin::OnNCActivate(BOOL active) {
- if (delegate_->CanActivate())
- delegate_->OnNativeWidgetActivationChanged(!!active);
-
- if (!GetWidget()->non_client_view()) {
- SetMsgHandled(FALSE);
- return 0;
- }
-
- if (!delegate_->CanActivate())
- return TRUE;
-
- // The frame may need to redraw as a result of the activation change.
- // We can get WM_NCACTIVATE before we're actually visible. If we're not
- // visible, no need to paint.
- if (IsVisible())
- GetWidget()->non_client_view()->SchedulePaint();
-
- if (!GetWidget()->ShouldUseNativeFrame()) {
- // TODO(beng, et al): Hack to redraw this window and child windows
- // synchronously upon activation. Not all child windows are redrawing
- // themselves leading to issues like http://crbug.com/74604
- // We redraw out-of-process HWNDs asynchronously to avoid hanging the
- // whole app if a child HWND belonging to a hung plugin is encountered.
- RedrawWindow(GetNativeView(), NULL, NULL,
- RDW_NOCHILDREN | RDW_INVALIDATE | RDW_UPDATENOW);
- EnumChildWindows(GetNativeView(), EnumChildWindowsForRedraw, NULL);
- }
-
- // If we're active again, we should be allowed to render as inactive, so
- // tell the non-client view.
- bool inactive_rendering_disabled = delegate_->IsInactiveRenderingDisabled();
- if (IsActive())
- delegate_->EnableInactiveRendering();
-
- // Avoid DefWindowProc non-client rendering over our custom frame on newer
- // Windows versions only (breaks taskbar activation indication on XP/Vista).
- if (!GetWidget()->ShouldUseNativeFrame() &&
- base::win::GetVersion() > base::win::VERSION_VISTA) {
- SetMsgHandled(TRUE);
- return TRUE;
- }
-
- return DefWindowProcWithRedrawLock(
- WM_NCACTIVATE, inactive_rendering_disabled || active, 0);
+ return message_handler_->OnNCActivate(active);
}
LRESULT NativeWidgetWin::OnNCCalcSize(BOOL mode, LPARAM l_param) {
@@ -1827,17 +1646,7 @@ LRESULT NativeWidgetWin::OnNCUAHDrawFrame(UINT msg,
}
LRESULT NativeWidgetWin::OnNotify(int w_param, NMHDR* l_param) {
- // We can be sent this message before the tooltip manager is created, if a
- // subclass overrides OnCreate and creates some kind of Windows control there
- // that sends WM_NOTIFY messages.
- if (tooltip_manager_.get()) {
- bool handled;
- LRESULT result = tooltip_manager_->OnNotify(w_param, l_param, &handled);
- SetMsgHandled(handled);
- return result;
- }
- SetMsgHandled(FALSE);
- return 0;
+ return message_handler_->OnNotify(w_param, l_param);
}
void NativeWidgetWin::OnPaint(HDC dc) {
@@ -1867,8 +1676,7 @@ LRESULT NativeWidgetWin::OnPowerBroadcast(DWORD power_event, DWORD data) {
LRESULT NativeWidgetWin::OnReflectedMessage(UINT msg,
WPARAM w_param,
LPARAM l_param) {
- SetMsgHandled(FALSE);
- return 0;
+ return message_handler_->OnReflectedMessage(msg, w_param, l_param);
}
LRESULT NativeWidgetWin::OnSetCursor(UINT message,
@@ -1890,19 +1698,7 @@ LRESULT NativeWidgetWin::OnSetText(const wchar_t* text) {
}
void NativeWidgetWin::OnSettingChange(UINT flags, const wchar_t* section) {
- if (!GetParent() && (flags == SPI_SETWORKAREA) &&
- !GetWidget()->widget_delegate()->WillProcessWorkAreaChange()) {
- // Fire a dummy SetWindowPos() call, so we'll trip the code in
- // OnWindowPosChanging() below that notices work area changes.
- ::SetWindowPos(GetNativeView(), 0, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE |
- SWP_NOZORDER | SWP_NOREDRAW | SWP_NOACTIVATE | SWP_NOOWNERZORDER);
- SetMsgHandled(TRUE);
- } else {
- // TODO(beng): move to Widget.
- if (flags == SPI_SETWORKAREA)
- GetWidget()->widget_delegate()->OnWorkAreaChanged();
- SetMsgHandled(FALSE);
- }
+ message_handler_->OnSettingChange(flags, section);
}
void NativeWidgetWin::OnSize(UINT param, const CSize& size) {
@@ -2192,6 +1988,18 @@ bool NativeWidgetWin::IsUsingCustomFrame() const {
return !GetWidget()->ShouldUseNativeFrame();
}
+void NativeWidgetWin::SchedulePaint() {
+ GetWidget()->GetRootView()->SchedulePaint();
+}
+
+void NativeWidgetWin::EnableInactiveRendering() {
+ delegate_->EnableInactiveRendering();
+}
+
+bool NativeWidgetWin::IsInactiveRenderingDisabled() {
+ return delegate_->IsInactiveRenderingDisabled();
+}
+
bool NativeWidgetWin::CanResize() const {
return GetWidget()->widget_delegate()->CanResize();
}
@@ -2204,6 +2012,10 @@ bool NativeWidgetWin::CanActivate() const {
return delegate_->CanActivate();
}
+bool NativeWidgetWin::WillProcessWorkAreaChange() const {
+ return GetWidget()->widget_delegate()->WillProcessWorkAreaChange();
+}
+
int NativeWidgetWin::GetNonClientComponent(const gfx::Point& point) const {
return delegate_->GetNonClientComponent(point);
}
@@ -2212,16 +2024,30 @@ void NativeWidgetWin::GetWindowMask(const gfx::Size& size, gfx::Path* path) {
GetWidget()->non_client_view()->GetWindowMask(size, path);
}
+void NativeWidgetWin::GetMinMaxSize(gfx::Size* min_size,
+ gfx::Size* max_size) const {
+ *min_size = delegate_->GetMinimumSize();
+ *max_size = delegate_->GetMaximumSize();
+}
+
InputMethod* NativeWidgetWin::GetInputMethod() {
return GetWidget()->GetInputMethodDirect();
}
+gfx::NativeViewAccessible NativeWidgetWin::GetNativeViewAccessible() {
+ return GetWidget()->GetRootView()->GetNativeViewAccessible();
+}
+
void NativeWidgetWin::HandleAppDeactivated() {
// Another application was activated, we should reset any state that
// disables inactive rendering now.
delegate_->EnableInactiveRendering();
}
+void NativeWidgetWin::HandleActivationChanged(bool active) {
+ delegate_->OnNativeWidgetActivationChanged(active);
+}
+
bool NativeWidgetWin::HandleAppCommand(short command) {
// We treat APPCOMMAND ids as an extension of our command namespace, and just
// let the delegate figure out what to do...
@@ -2241,6 +2067,49 @@ bool NativeWidgetWin::HandleCommand(int command) {
return GetWidget()->widget_delegate()->ExecuteWindowsCommand(command);
}
+void NativeWidgetWin::HandleCreate() {
+ // TODO(beng): much of this could/should maybe move to HWNDMessageHandler.
+
+ SetNativeWindowProperty(kNativeWidgetKey, this);
+ CHECK_EQ(this, GetNativeWidgetForNativeView(hwnd()));
+
+ use_layered_buffer_ = !!(window_ex_style() & WS_EX_LAYERED);
+
+ props_.push_back(ui::SetWindowSupportsRerouteMouseWheel(hwnd()));
+
+ drop_target_ = new DropTargetWin(
+ static_cast<internal::RootView*>(GetWidget()->GetRootView()));
+
+ // We need to add ourselves as a message loop observer so that we can repaint
+ // aggressively if the contents of our window become invalid. Unfortunately
+ // WM_PAINT messages are starved and we get flickery redrawing when resizing
+ // if we do not do this.
+ MessageLoopForUI::current()->AddObserver(this);
+
+ // Windows special DWM window frame requires a special tooltip manager so
+ // that window controls in Chrome windows don't flicker when you move your
+ // mouse over them. See comment in aero_tooltip_manager.h.
+ Widget* widget = GetWidget()->GetTopLevelWidget();
+ if (widget && widget->ShouldUseNativeFrame()) {
+ tooltip_manager_.reset(new AeroTooltipManager(GetWidget()));
+ } else {
+ tooltip_manager_.reset(new TooltipManagerWin(GetWidget()));
+ }
+ if (!tooltip_manager_->Init()) {
+ // There was a problem creating the TooltipManager. Common error is 127.
+ // See 82193 for details.
+ LOG_GETLASTERROR(WARNING) << "tooltip creation failed, disabling tooltips";
+ tooltip_manager_.reset();
+ }
+
+ // We need to allow the delegate to size its contents since the window may not
+ // receive a size notification when its initial bounds are specified at window
+ // creation time.
+ ClientAreaSizeChanged();
+
+ delegate_->OnNativeWidgetCreated();
+}
+
void NativeWidgetWin::HandleDestroy() {
delegate_->OnNativeWidgetDestroying();
if (drop_target_.get()) {
@@ -2275,6 +2144,10 @@ void NativeWidgetWin::HandleMove() {
delegate_->OnNativeWidgetMove();
}
+void NativeWidgetWin::HandleWorkAreaChanged() {
+ GetWidget()->widget_delegate()->OnWorkAreaChanged();
+}
+
void NativeWidgetWin::HandleNativeFocus(HWND last_focused_window) {
delegate_->OnNativeFocus(last_focused_window);
}
@@ -2283,6 +2156,25 @@ void NativeWidgetWin::HandleNativeBlur(HWND focused_window) {
delegate_->OnNativeBlur(focused_window);
}
+void NativeWidgetWin::HandleScreenReaderDetected() {
+ // TODO(beng): just consolidate this with OnScreenReaderDetected.
+ OnScreenReaderDetected();
+}
+
+bool NativeWidgetWin::HandleTooltipNotify(int w_param,
+ NMHDR* l_param,
+ LRESULT* l_result) {
+ // We can be sent this message before the tooltip manager is created, if a
+ // subclass overrides OnCreate and creates some kind of Windows control there
+ // that sends WM_NOTIFY messages.
+ if (tooltip_manager_.get()) {
+ bool handled;
+ *l_result = tooltip_manager_->OnNotify(w_param, l_param, &handled);
+ return handled;
+ }
+ return false;
+}
+
NativeWidgetWin* NativeWidgetWin::AsNativeWidgetWin() {
return this;
}