Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(6)

Side by Side Diff: ui/views/widget/native_widget_win.cc

Issue 10871077: Move more code from NWW to HWNDMessageHandler. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 8 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « ui/views/widget/native_widget_win.h ('k') | ui/views/win/DEPS » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "ui/views/widget/native_widget_win.h" 5 #include "ui/views/widget/native_widget_win.h"
6 6
7 #include <dwmapi.h> 7 #include <dwmapi.h>
8 #include <shellapi.h> 8 #include <shellapi.h>
9 9
10 #include <algorithm> 10 #include <algorithm>
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
59 #endif 59 #endif
60 60
61 #pragma comment(lib, "dwmapi.lib") 61 #pragma comment(lib, "dwmapi.lib")
62 62
63 using ui::ViewProp; 63 using ui::ViewProp;
64 64
65 namespace views { 65 namespace views {
66 66
67 namespace { 67 namespace {
68 68
69 // MoveLoopMouseWatcher is used to determine if the user canceled or completed a
70 // move. win32 doesn't appear to offer a way to determine the result of a move,
71 // so we install hooks to determine if we got a mouse up and assume the move
72 // completed.
73 class MoveLoopMouseWatcher {
74 public:
75 explicit MoveLoopMouseWatcher(NativeWidgetWin* host);
76 ~MoveLoopMouseWatcher();
77
78 // Returns true if the mouse is up, or if we couldn't install the hook.
79 bool got_mouse_up() const { return got_mouse_up_; }
80
81 private:
82 // Instance that owns the hook. We only allow one instance to hook the mouse
83 // at a time.
84 static MoveLoopMouseWatcher* instance_;
85
86 // Key and mouse callbacks from the hook.
87 static LRESULT CALLBACK MouseHook(int n_code, WPARAM w_param, LPARAM l_param);
88 static LRESULT CALLBACK KeyHook(int n_code, WPARAM w_param, LPARAM l_param);
89
90 void Unhook();
91
92 // NativeWidgetWin that created us.
93 NativeWidgetWin* host_;
94
95 // Did we get a mouse up?
96 bool got_mouse_up_;
97
98 // Hook identifiers.
99 HHOOK mouse_hook_;
100 HHOOK key_hook_;
101
102 DISALLOW_COPY_AND_ASSIGN(MoveLoopMouseWatcher);
103 };
104
105 // static
106 MoveLoopMouseWatcher* MoveLoopMouseWatcher::instance_ = NULL;
107
108 MoveLoopMouseWatcher::MoveLoopMouseWatcher(NativeWidgetWin* host)
109 : host_(host),
110 got_mouse_up_(false),
111 mouse_hook_(NULL),
112 key_hook_(NULL) {
113 // Only one instance can be active at a time.
114 if (instance_)
115 instance_->Unhook();
116
117 mouse_hook_ = SetWindowsHookEx(
118 WH_MOUSE, &MouseHook, NULL, GetCurrentThreadId());
119 if (mouse_hook_) {
120 instance_ = this;
121 // We don't care if setting the key hook succeeded.
122 key_hook_ = SetWindowsHookEx(
123 WH_KEYBOARD, &KeyHook, NULL, GetCurrentThreadId());
124 }
125 if (instance_ != this) {
126 // Failed installation. Assume we got a mouse up in this case, otherwise
127 // we'll think all drags were canceled.
128 got_mouse_up_ = true;
129 }
130 }
131
132 MoveLoopMouseWatcher::~MoveLoopMouseWatcher() {
133 Unhook();
134 }
135
136 void MoveLoopMouseWatcher::Unhook() {
137 if (instance_ != this)
138 return;
139
140 DCHECK(mouse_hook_);
141 UnhookWindowsHookEx(mouse_hook_);
142 if (key_hook_)
143 UnhookWindowsHookEx(key_hook_);
144 key_hook_ = NULL;
145 mouse_hook_ = NULL;
146 instance_ = NULL;
147 }
148
149 // static
150 LRESULT CALLBACK MoveLoopMouseWatcher::MouseHook(int n_code,
151 WPARAM w_param,
152 LPARAM l_param) {
153 DCHECK(instance_);
154 if (n_code == HC_ACTION && w_param == WM_LBUTTONUP)
155 instance_->got_mouse_up_ = true;
156 return CallNextHookEx(instance_->mouse_hook_, n_code, w_param, l_param);
157 }
158
159 // static
160 LRESULT CALLBACK MoveLoopMouseWatcher::KeyHook(int n_code,
161 WPARAM w_param,
162 LPARAM l_param) {
163 if (n_code == HC_ACTION && w_param == VK_ESCAPE) {
164 if (base::win::GetVersion() >= base::win::VERSION_VISTA) {
165 int value = TRUE;
166 HRESULT result = DwmSetWindowAttribute(
167 instance_->host_->GetNativeView(),
168 DWMWA_TRANSITIONS_FORCEDISABLED,
169 &value,
170 sizeof(value));
171 }
172 // Hide the window on escape, otherwise the window is visibly going to snap
173 // back to the original location before we close it.
174 // This behavior is specific to tab dragging, in that we generally wouldn't
175 // want this functionality if we have other consumers using this API.
176 instance_->host_->Hide();
177 }
178 return CallNextHookEx(instance_->key_hook_, n_code, w_param, l_param);
179 }
180
181 // Get the source HWND of the specified message. Depending on the message, the 69 // Get the source HWND of the specified message. Depending on the message, the
182 // source HWND is encoded in either the WPARAM or the LPARAM value. 70 // source HWND is encoded in either the WPARAM or the LPARAM value.
183 HWND GetControlHWNDForMessage(UINT message, WPARAM w_param, LPARAM l_param) { 71 HWND GetControlHWNDForMessage(UINT message, WPARAM w_param, LPARAM l_param) {
184 // Each of the following messages can be sent by a child HWND and must be 72 // Each of the following messages can be sent by a child HWND and must be
185 // forwarded to its associated NativeControlWin for handling. 73 // forwarded to its associated NativeControlWin for handling.
186 switch (message) { 74 switch (message) {
187 case WM_NOTIFY: 75 case WM_NOTIFY:
188 return reinterpret_cast<NMHDR*>(l_param)->hwndFrom; 76 return reinterpret_cast<NMHDR*>(l_param)->hwndFrom;
189 case WM_COMMAND: 77 case WM_COMMAND:
190 return reinterpret_cast<HWND>(l_param); 78 return reinterpret_cast<HWND>(l_param);
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
226 // child HWND beneath the original HWND. 114 // child HWND beneath the original HWND.
227 BOOL CALLBACK EnumerateChildWindowsForNativeWidgets(HWND hwnd, LPARAM l_param) { 115 BOOL CALLBACK EnumerateChildWindowsForNativeWidgets(HWND hwnd, LPARAM l_param) {
228 Widget* widget = Widget::GetWidgetForNativeView(hwnd); 116 Widget* widget = Widget::GetWidgetForNativeView(hwnd);
229 if (widget) { 117 if (widget) {
230 Widget::Widgets* widgets = reinterpret_cast<Widget::Widgets*>(l_param); 118 Widget::Widgets* widgets = reinterpret_cast<Widget::Widgets*>(l_param);
231 widgets->insert(widget); 119 widgets->insert(widget);
232 } 120 }
233 return TRUE; 121 return TRUE;
234 } 122 }
235 123
236 // Callback used to notify child windows that the top level window received a
237 // DWMCompositionChanged message.
238 BOOL CALLBACK SendDwmCompositionChanged(HWND window, LPARAM param) {
239 SendMessage(window, WM_DWMCOMPOSITIONCHANGED, 0, 0);
240 return TRUE;
241 }
242
243 // Enables or disables the menu item for the specified command and menu. 124 // Enables or disables the menu item for the specified command and menu.
244 void EnableMenuItem(HMENU menu, UINT command, bool enabled) { 125 void EnableMenuItem(HMENU menu, UINT command, bool enabled) {
245 UINT flags = MF_BYCOMMAND | (enabled ? MF_ENABLED : MF_DISABLED | MF_GRAYED); 126 UINT flags = MF_BYCOMMAND | (enabled ? MF_ENABLED : MF_DISABLED | MF_GRAYED);
246 EnableMenuItem(menu, command, flags); 127 EnableMenuItem(menu, command, flags);
247 } 128 }
248 129
249 // See comments in OnNCPaint() for details of this struct.
250 struct ClipState {
251 // The window being painted.
252 HWND parent;
253
254 // DC painting to.
255 HDC dc;
256
257 // Origin of the window in terms of the screen.
258 int x;
259 int y;
260 };
261
262 // See comments in OnNCPaint() for details of this function.
263 static BOOL CALLBACK ClipDCToChild(HWND window, LPARAM param) {
264 ClipState* clip_state = reinterpret_cast<ClipState*>(param);
265 if (GetParent(window) == clip_state->parent && IsWindowVisible(window)) {
266 RECT bounds;
267 GetWindowRect(window, &bounds);
268 ExcludeClipRect(clip_state->dc,
269 bounds.left - clip_state->x,
270 bounds.top - clip_state->y,
271 bounds.right - clip_state->x,
272 bounds.bottom - clip_state->y);
273 }
274 return TRUE;
275 }
276
277 // Links the HWND to its NativeWidget. 130 // Links the HWND to its NativeWidget.
278 const char* const kNativeWidgetKey = "__VIEWS_NATIVE_WIDGET__"; 131 const char* const kNativeWidgetKey = "__VIEWS_NATIVE_WIDGET__";
279 132
280 const int kDragFrameWindowAlpha = 200; 133 const int kDragFrameWindowAlpha = 200;
281 134
282 } // namespace 135 } // namespace
283 136
284 // static 137 // static
285 bool NativeWidgetWin::screen_reader_active_ = false; 138 bool NativeWidgetWin::screen_reader_active_ = false;
286 139
287 //////////////////////////////////////////////////////////////////////////////// 140 ////////////////////////////////////////////////////////////////////////////////
288 // NativeWidgetWin, public: 141 // NativeWidgetWin, public:
289 142
290 NativeWidgetWin::NativeWidgetWin(internal::NativeWidgetDelegate* delegate) 143 NativeWidgetWin::NativeWidgetWin(internal::NativeWidgetDelegate* delegate)
291 : delegate_(delegate), 144 : delegate_(delegate),
292 ALLOW_THIS_IN_INITIALIZER_LIST(close_widget_factory_(this)), 145 ALLOW_THIS_IN_INITIALIZER_LIST(close_widget_factory_(this)),
293 use_layered_buffer_(false),
294 layered_alpha_(255),
295 ALLOW_THIS_IN_INITIALIZER_LIST(paint_layered_window_factory_(this)),
296 ownership_(Widget::InitParams::NATIVE_WIDGET_OWNS_WIDGET), 146 ownership_(Widget::InitParams::NATIVE_WIDGET_OWNS_WIDGET),
297 can_update_layered_window_(true),
298 restore_focus_when_enabled_(false), 147 restore_focus_when_enabled_(false),
299 accessibility_view_events_index_(-1), 148 accessibility_view_events_index_(-1),
300 accessibility_view_events_(kMaxAccessibilityViewEvents), 149 accessibility_view_events_(kMaxAccessibilityViewEvents),
301 previous_cursor_(NULL),
302 restored_enabled_(false), 150 restored_enabled_(false),
303 has_non_client_view_(false), 151 has_non_client_view_(false),
304 ALLOW_THIS_IN_INITIALIZER_LIST( 152 ALLOW_THIS_IN_INITIALIZER_LIST(
305 message_handler_(new HWNDMessageHandler(this))) { 153 message_handler_(new HWNDMessageHandler(this))) {
306 } 154 }
307 155
308 NativeWidgetWin::~NativeWidgetWin() { 156 NativeWidgetWin::~NativeWidgetWin() {
309 if (ownership_ == Widget::InitParams::NATIVE_WIDGET_OWNS_WIDGET) 157 if (ownership_ == Widget::InitParams::NATIVE_WIDGET_OWNS_WIDGET)
310 delete delegate_; 158 delete delegate_;
311 else 159 else
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
392 void NativeWidgetWin::UpdateFrameAfterFrameChange() { 240 void NativeWidgetWin::UpdateFrameAfterFrameChange() {
393 // We've either gained or lost a custom window region, so reset it now. 241 // We've either gained or lost a custom window region, so reset it now.
394 message_handler_->ResetWindowRegion(true); 242 message_handler_->ResetWindowRegion(true);
395 } 243 }
396 244
397 bool NativeWidgetWin::ShouldUseNativeFrame() const { 245 bool NativeWidgetWin::ShouldUseNativeFrame() const {
398 return ui::win::IsAeroGlassEnabled(); 246 return ui::win::IsAeroGlassEnabled();
399 } 247 }
400 248
401 void NativeWidgetWin::FrameTypeChanged() { 249 void NativeWidgetWin::FrameTypeChanged() {
402 // Called when the frame type could possibly be changing (theme change or 250 message_handler_->FrameTypeChanged();
403 // DWM composition change).
404 if (base::win::GetVersion() >= base::win::VERSION_VISTA) {
405 // We need to toggle the rendering policy of the DWM/glass frame as we
406 // change from opaque to glass. "Non client rendering enabled" means that
407 // the DWM's glass non-client rendering is enabled, which is why
408 // DWMNCRP_ENABLED is used for the native frame case. _DISABLED means the
409 // DWM doesn't render glass, and so is used in the custom frame case.
410 DWMNCRENDERINGPOLICY policy = GetWidget()->ShouldUseNativeFrame() ?
411 DWMNCRP_ENABLED : DWMNCRP_DISABLED;
412 DwmSetWindowAttribute(GetNativeView(), DWMWA_NCRENDERING_POLICY,
413 &policy, sizeof(DWMNCRENDERINGPOLICY));
414 }
415
416 // Send a frame change notification, since the non-client metrics have
417 // changed.
418 message_handler_->SendFrameChanged();
419
420 // Update the non-client view with the correct frame view for the active frame
421 // type.
422 GetWidget()->non_client_view()->UpdateFrame();
423
424 // WM_DWMCOMPOSITIONCHANGED is only sent to top level windows, however we want
425 // to notify our children too, since we can have MDI child windows who need to
426 // update their appearance.
427 EnumChildWindows(GetNativeView(), &SendDwmCompositionChanged, NULL);
428 } 251 }
429 252
430 Widget* NativeWidgetWin::GetWidget() { 253 Widget* NativeWidgetWin::GetWidget() {
431 return delegate_->AsWidget(); 254 return delegate_->AsWidget();
432 } 255 }
433 256
434 const Widget* NativeWidgetWin::GetWidget() const { 257 const Widget* NativeWidgetWin::GetWidget() const {
435 return delegate_->AsWidget(); 258 return delegate_->AsWidget();
436 } 259 }
437 260
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
489 return tooltip_manager_.get(); 312 return tooltip_manager_.get();
490 } 313 }
491 314
492 bool NativeWidgetWin::IsScreenReaderActive() const { 315 bool NativeWidgetWin::IsScreenReaderActive() const {
493 return screen_reader_active_; 316 return screen_reader_active_;
494 } 317 }
495 318
496 void NativeWidgetWin::SendNativeAccessibilityEvent( 319 void NativeWidgetWin::SendNativeAccessibilityEvent(
497 View* view, 320 View* view,
498 ui::AccessibilityTypes::Event event_type) { 321 ui::AccessibilityTypes::Event event_type) {
499 // Now call the Windows-specific method to notify MSAA clients of this
500 // event. The widget gives us a temporary unique child ID to associate
501 // with this view so that clients can call get_accChild in
502 // NativeViewAccessibilityWin to retrieve the IAccessible associated
503 // with this view.
504 int child_id = AddAccessibilityViewEvent(view); 322 int child_id = AddAccessibilityViewEvent(view);
505 ::NotifyWinEvent(NativeViewAccessibilityWin::MSAAEvent(event_type), 323 message_handler_->SendNativeAccessibilityEvent(child_id, event_type);
506 GetNativeView(), OBJID_CLIENT, child_id);
507 } 324 }
508 325
509 void NativeWidgetWin::SetCapture() { 326 void NativeWidgetWin::SetCapture() {
510 message_handler_->SetCapture(); 327 message_handler_->SetCapture();
511 } 328 }
512 329
513 void NativeWidgetWin::ReleaseCapture() { 330 void NativeWidgetWin::ReleaseCapture() {
514 message_handler_->ReleaseCapture(); 331 message_handler_->ReleaseCapture();
515 } 332 }
516 333
517 bool NativeWidgetWin::HasCapture() const { 334 bool NativeWidgetWin::HasCapture() const {
518 return message_handler_->HasCapture(); 335 return message_handler_->HasCapture();
519 } 336 }
520 337
521 InputMethod* NativeWidgetWin::CreateInputMethod() { 338 InputMethod* NativeWidgetWin::CreateInputMethod() {
522 return message_handler_->CreateInputMethod(); 339 return message_handler_->CreateInputMethod();
523 } 340 }
524 341
525 internal::InputMethodDelegate* NativeWidgetWin::GetInputMethodDelegate() { 342 internal::InputMethodDelegate* NativeWidgetWin::GetInputMethodDelegate() {
526 return message_handler_.get(); 343 return message_handler_.get();
527 } 344 }
528 345
529 void NativeWidgetWin::CenterWindow(const gfx::Size& size) { 346 void NativeWidgetWin::CenterWindow(const gfx::Size& size) {
530 HWND parent = GetParent(); 347 message_handler_->CenterWindow(size);
531 if (!IsWindow())
532 parent = ::GetWindow(GetNativeView(), GW_OWNER);
533 ui::CenterAndSizeWindow(parent, GetNativeView(), size);
534 } 348 }
535 349
536 void NativeWidgetWin::GetWindowPlacement( 350 void NativeWidgetWin::GetWindowPlacement(
537 gfx::Rect* bounds, 351 gfx::Rect* bounds,
538 ui::WindowShowState* show_state) const { 352 ui::WindowShowState* show_state) const {
539 message_handler_->GetWindowPlacement(bounds, show_state); 353 message_handler_->GetWindowPlacement(bounds, show_state);
540 } 354 }
541 355
542 void NativeWidgetWin::SetWindowTitle(const string16& title) { 356 void NativeWidgetWin::SetWindowTitle(const string16& title) {
543 SetWindowText(GetNativeView(), title.c_str()); 357 SetWindowText(GetNativeView(), title.c_str());
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after
758 } 572 }
759 573
760 bool NativeWidgetWin::IsFullscreen() const { 574 bool NativeWidgetWin::IsFullscreen() const {
761 return message_handler_->fullscreen_handler()->fullscreen(); 575 return message_handler_->fullscreen_handler()->fullscreen();
762 } 576 }
763 577
764 bool NativeWidgetWin::IsInMetroSnapMode() const { 578 bool NativeWidgetWin::IsInMetroSnapMode() const {
765 return message_handler_->fullscreen_handler()->metro_snap(); 579 return message_handler_->fullscreen_handler()->metro_snap();
766 } 580 }
767 581
582 void NativeWidgetWin::SetCanUpdateLayeredWindow(bool can_update) {
583 message_handler_->set_can_update_layered_window(can_update);
584 }
585
768 void NativeWidgetWin::SetOpacity(unsigned char opacity) { 586 void NativeWidgetWin::SetOpacity(unsigned char opacity) {
769 layered_alpha_ = static_cast<BYTE>(opacity); 587 message_handler_->SetOpacity(static_cast<BYTE>(opacity));
770 GetWidget()->GetRootView()->SchedulePaint(); 588 GetWidget()->GetRootView()->SchedulePaint();
771 } 589 }
772 590
773 void NativeWidgetWin::SetUseDragFrame(bool use_drag_frame) { 591 void NativeWidgetWin::SetUseDragFrame(bool use_drag_frame) {
774 if (use_drag_frame) { 592 if (use_drag_frame) {
775 // Make the frame slightly transparent during the drag operation. 593 // Make the frame slightly transparent during the drag operation.
776 drag_frame_saved_window_style_ = GetWindowLong(GWL_STYLE); 594 drag_frame_saved_window_style_ = GetWindowLong(GWL_STYLE);
777 drag_frame_saved_window_ex_style_ = GetWindowLong(GWL_EXSTYLE); 595 drag_frame_saved_window_ex_style_ = GetWindowLong(GWL_EXSTYLE);
778 SetWindowLong(GWL_EXSTYLE, 596 SetWindowLong(GWL_EXSTYLE,
779 drag_frame_saved_window_ex_style_ | WS_EX_LAYERED); 597 drag_frame_saved_window_ex_style_ | WS_EX_LAYERED);
(...skipping 17 matching lines...) Expand all
797 } 615 }
798 616
799 void NativeWidgetWin::RunShellDrag(View* view, 617 void NativeWidgetWin::RunShellDrag(View* view,
800 const ui::OSExchangeData& data, 618 const ui::OSExchangeData& data,
801 const gfx::Point& location, 619 const gfx::Point& location,
802 int operation) { 620 int operation) {
803 views::RunShellDrag(NULL, data, location, operation); 621 views::RunShellDrag(NULL, data, location, operation);
804 } 622 }
805 623
806 void NativeWidgetWin::SchedulePaintInRect(const gfx::Rect& rect) { 624 void NativeWidgetWin::SchedulePaintInRect(const gfx::Rect& rect) {
807 if (use_layered_buffer_) { 625 message_handler_->SchedulePaintInRect(rect);
808 // We must update the back-buffer immediately, since Windows' handling of
809 // invalid rects is somewhat mysterious.
810 invalid_rect_ = invalid_rect_.Union(rect);
811
812 // In some situations, such as drag and drop, when Windows itself runs a
813 // nested message loop our message loop appears to be starved and we don't
814 // receive calls to DidProcessMessage(). This only seems to affect layered
815 // windows, so we schedule a redraw manually using a task, since those never
816 // seem to be starved. Also, wtf.
817 if (!paint_layered_window_factory_.HasWeakPtrs()) {
818 MessageLoop::current()->PostTask(
819 FROM_HERE,
820 base::Bind(&NativeWidgetWin::RedrawLayeredWindowContents,
821 paint_layered_window_factory_.GetWeakPtr()));
822 }
823 } else {
824 // InvalidateRect() expects client coordinates.
825 RECT r = rect.ToRECT();
826 InvalidateRect(hwnd(), &r, FALSE);
827 }
828 } 626 }
829 627
830 void NativeWidgetWin::SetCursor(gfx::NativeCursor cursor) { 628 void NativeWidgetWin::SetCursor(gfx::NativeCursor cursor) {
831 if (cursor) { 629 message_handler_->SetCursor(cursor);
832 previous_cursor_ = ::SetCursor(cursor);
833 } else if (previous_cursor_) {
834 ::SetCursor(previous_cursor_);
835 previous_cursor_ = NULL;
836 }
837 } 630 }
838 631
839 void NativeWidgetWin::ClearNativeFocus() { 632 void NativeWidgetWin::ClearNativeFocus() {
840 message_handler_->ClearNativeFocus(); 633 message_handler_->ClearNativeFocus();
841 } 634 }
842 635
843 void NativeWidgetWin::FocusNativeView(gfx::NativeView native_view) { 636 void NativeWidgetWin::FocusNativeView(gfx::NativeView native_view) {
844 message_handler_->FocusHWND(native_view); 637 message_handler_->FocusHWND(native_view);
845 } 638 }
846 639
847 gfx::Rect NativeWidgetWin::GetWorkAreaBoundsInScreen() const { 640 gfx::Rect NativeWidgetWin::GetWorkAreaBoundsInScreen() const {
848 return gfx::Screen::GetDisplayNearestWindow(GetNativeView()).work_area(); 641 return message_handler_->GetWorkAreaBoundsInScreen();
849 } 642 }
850 643
851 void NativeWidgetWin::SetInactiveRenderingDisabled(bool value) { 644 void NativeWidgetWin::SetInactiveRenderingDisabled(bool value) {
852 } 645 }
853 646
854 Widget::MoveLoopResult NativeWidgetWin::RunMoveLoop( 647 Widget::MoveLoopResult NativeWidgetWin::RunMoveLoop(
855 const gfx::Point& drag_offset) { 648 const gfx::Point& drag_offset) {
856 ReleaseCapture(); 649 return message_handler_->RunMoveLoop(drag_offset) ?
857 MoveLoopMouseWatcher watcher(this); 650 Widget::MOVE_LOOP_SUCCESSFUL : Widget::MOVE_LOOP_CANCELED;
858 SendMessage(hwnd(), WM_SYSCOMMAND, SC_MOVE | 0x0002, GetMessagePos());
859 // Windows doesn't appear to offer a way to determine whether the user
860 // canceled the move or not. We assume if the user released the mouse it was
861 // successful.
862 return watcher.got_mouse_up() ? Widget::MOVE_LOOP_SUCCESSFUL :
863 Widget::MOVE_LOOP_CANCELED;
864 } 651 }
865 652
866 void NativeWidgetWin::EndMoveLoop() { 653 void NativeWidgetWin::EndMoveLoop() {
867 SendMessage(hwnd(), WM_CANCELMODE, 0, 0); 654 SendMessage(hwnd(), WM_CANCELMODE, 0, 0);
868 } 655 }
869 656
870 void NativeWidgetWin::SetVisibilityChangedAnimationsEnabled(bool value) { 657 void NativeWidgetWin::SetVisibilityChangedAnimationsEnabled(bool value) {
871 message_handler_->SetVisibilityChangedAnimationsEnabled(value); 658 message_handler_->SetVisibilityChangedAnimationsEnabled(value);
872 } 659 }
873 660
874 //////////////////////////////////////////////////////////////////////////////// 661 ////////////////////////////////////////////////////////////////////////////////
875 // NativeWidgetWin, MessageLoop::Observer implementation: 662 // NativeWidgetWin, MessageLoop::Observer implementation:
876 663
877 base::EventStatus NativeWidgetWin::WillProcessEvent( 664 base::EventStatus NativeWidgetWin::WillProcessEvent(
878 const base::NativeEvent& event) { 665 const base::NativeEvent& event) {
879 return base::EVENT_CONTINUE; 666 return base::EVENT_CONTINUE;
880 } 667 }
881 668
882 void NativeWidgetWin::DidProcessEvent(const base::NativeEvent& event) { 669 void NativeWidgetWin::DidProcessEvent(const base::NativeEvent& event) {
883 RedrawInvalidRect(); 670 message_handler_->RedrawInvalidRect();
884 } 671 }
885 672
886 //////////////////////////////////////////////////////////////////////////////// 673 ////////////////////////////////////////////////////////////////////////////////
887 // NativeWidgetWin, WindowImpl overrides: 674 // NativeWidgetWin, WindowImpl overrides:
888 675
889 HICON NativeWidgetWin::GetDefaultWindowIcon() const { 676 HICON NativeWidgetWin::GetDefaultWindowIcon() const {
890 if (ViewsDelegate::views_delegate) 677 if (ViewsDelegate::views_delegate)
891 return ViewsDelegate::views_delegate->GetDefaultWindowIcon(); 678 return ViewsDelegate::views_delegate->GetDefaultWindowIcon();
892 return NULL; 679 return NULL;
893 } 680 }
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
957 message_handler_->OnClose(); 744 message_handler_->OnClose();
958 } 745 }
959 746
960 void NativeWidgetWin::OnCommand(UINT notification_code, 747 void NativeWidgetWin::OnCommand(UINT notification_code,
961 int command_id, 748 int command_id,
962 HWND window) { 749 HWND window) {
963 message_handler_->OnCommand(notification_code, command_id, window); 750 message_handler_->OnCommand(notification_code, command_id, window);
964 } 751 }
965 752
966 LRESULT NativeWidgetWin::OnCreate(CREATESTRUCT* create_struct) { 753 LRESULT NativeWidgetWin::OnCreate(CREATESTRUCT* create_struct) {
967 // TODO(beng): move to message_handler_. Needed before
968 // ClientAreaSizeChanged().
969 use_layered_buffer_ = !!(window_ex_style() & WS_EX_LAYERED);
970 return message_handler_->OnCreate(create_struct); 754 return message_handler_->OnCreate(create_struct);
971 } 755 }
972 756
973 void NativeWidgetWin::OnDestroy() { 757 void NativeWidgetWin::OnDestroy() {
974 message_handler_->OnDestroy(); 758 message_handler_->OnDestroy();
975 } 759 }
976 760
977 void NativeWidgetWin::OnDisplayChange(UINT bits_per_pixel, CSize screen_size) { 761 void NativeWidgetWin::OnDisplayChange(UINT bits_per_pixel, CSize screen_size) {
978 message_handler_->OnDisplayChange(bits_per_pixel, screen_size); 762 message_handler_->OnDisplayChange(bits_per_pixel, screen_size);
979 } 763 }
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
1077 861
1078 LRESULT NativeWidgetWin::OnNCCalcSize(BOOL mode, LPARAM l_param) { 862 LRESULT NativeWidgetWin::OnNCCalcSize(BOOL mode, LPARAM l_param) {
1079 return message_handler_->OnNCCalcSize(mode, l_param); 863 return message_handler_->OnNCCalcSize(mode, l_param);
1080 } 864 }
1081 865
1082 LRESULT NativeWidgetWin::OnNCHitTest(const CPoint& point) { 866 LRESULT NativeWidgetWin::OnNCHitTest(const CPoint& point) {
1083 return message_handler_->OnNCHitTest(point); 867 return message_handler_->OnNCHitTest(point);
1084 } 868 }
1085 869
1086 void NativeWidgetWin::OnNCPaint(HRGN rgn) { 870 void NativeWidgetWin::OnNCPaint(HRGN rgn) {
1087 // We only do non-client painting if we're not using the native frame. 871 message_handler_->OnNCPaint(rgn);
1088 // It's required to avoid some native painting artifacts from appearing when
1089 // the window is resized.
1090 if (!GetWidget()->non_client_view() || GetWidget()->ShouldUseNativeFrame()) {
1091 SetMsgHandled(FALSE);
1092 return;
1093 }
1094
1095 // We have an NC region and need to paint it. We expand the NC region to
1096 // include the dirty region of the root view. This is done to minimize
1097 // paints.
1098 CRect window_rect;
1099 GetWindowRect(&window_rect);
1100
1101 if (window_rect.Width() != GetWidget()->GetRootView()->width() ||
1102 window_rect.Height() != GetWidget()->GetRootView()->height()) {
1103 // If the size of the window differs from the size of the root view it
1104 // means we're being asked to paint before we've gotten a WM_SIZE. This can
1105 // happen when the user is interactively resizing the window. To avoid
1106 // mass flickering we don't do anything here. Once we get the WM_SIZE we'll
1107 // reset the region of the window which triggers another WM_NCPAINT and
1108 // all is well.
1109 return;
1110 }
1111
1112 CRect dirty_region;
1113 // A value of 1 indicates paint all.
1114 if (!rgn || rgn == reinterpret_cast<HRGN>(1)) {
1115 dirty_region = CRect(0, 0, window_rect.Width(), window_rect.Height());
1116 } else {
1117 RECT rgn_bounding_box;
1118 GetRgnBox(rgn, &rgn_bounding_box);
1119 if (!IntersectRect(&dirty_region, &rgn_bounding_box, &window_rect))
1120 return; // Dirty region doesn't intersect window bounds, bale.
1121
1122 // rgn_bounding_box is in screen coordinates. Map it to window coordinates.
1123 OffsetRect(&dirty_region, -window_rect.left, -window_rect.top);
1124 }
1125
1126 // In theory GetDCEx should do what we want, but I couldn't get it to work.
1127 // In particular the docs mentiond DCX_CLIPCHILDREN, but as far as I can tell
1128 // it doesn't work at all. So, instead we get the DC for the window then
1129 // manually clip out the children.
1130 HDC dc = GetWindowDC(GetNativeView());
1131 ClipState clip_state;
1132 clip_state.x = window_rect.left;
1133 clip_state.y = window_rect.top;
1134 clip_state.parent = GetNativeView();
1135 clip_state.dc = dc;
1136 EnumChildWindows(GetNativeView(), &ClipDCToChild,
1137 reinterpret_cast<LPARAM>(&clip_state));
1138
1139 gfx::Rect old_paint_region = invalid_rect();
1140
1141 if (!old_paint_region.IsEmpty()) {
1142 // The root view has a region that needs to be painted. Include it in the
1143 // region we're going to paint.
1144
1145 CRect old_paint_region_crect = old_paint_region.ToRECT();
1146 CRect tmp = dirty_region;
1147 UnionRect(&dirty_region, &tmp, &old_paint_region_crect);
1148 }
1149
1150 GetWidget()->GetRootView()->SchedulePaintInRect(gfx::Rect(dirty_region));
1151
1152 // gfx::CanvasSkiaPaint's destructor does the actual painting. As such, wrap
1153 // the following in a block to force paint to occur so that we can release
1154 // the dc.
1155 {
1156 gfx::CanvasSkiaPaint canvas(dc, true, dirty_region.left,
1157 dirty_region.top, dirty_region.Width(),
1158 dirty_region.Height());
1159 delegate_->OnNativeWidgetPaint(&canvas);
1160 }
1161
1162 ReleaseDC(GetNativeView(), dc);
1163 // When using a custom frame, we want to avoid calling DefWindowProc() since
1164 // that may render artifacts.
1165 SetMsgHandled(!GetWidget()->ShouldUseNativeFrame());
1166 } 872 }
1167 873
1168 LRESULT NativeWidgetWin::OnNCUAHDrawCaption(UINT msg, 874 LRESULT NativeWidgetWin::OnNCUAHDrawCaption(UINT msg,
1169 WPARAM w_param, 875 WPARAM w_param,
1170 LPARAM l_param) { 876 LPARAM l_param) {
1171 return message_handler_->OnNCUAHDrawCaption(msg, w_param, l_param); 877 return message_handler_->OnNCUAHDrawCaption(msg, w_param, l_param);
1172 } 878 }
1173 879
1174 LRESULT NativeWidgetWin::OnNCUAHDrawFrame(UINT msg, 880 LRESULT NativeWidgetWin::OnNCUAHDrawFrame(UINT msg,
1175 WPARAM w_param, 881 WPARAM w_param,
1176 LPARAM l_param) { 882 LPARAM l_param) {
1177 return message_handler_->OnNCUAHDrawFrame(msg, w_param, l_param); 883 return message_handler_->OnNCUAHDrawFrame(msg, w_param, l_param);
1178 } 884 }
1179 885
1180 LRESULT NativeWidgetWin::OnNotify(int w_param, NMHDR* l_param) { 886 LRESULT NativeWidgetWin::OnNotify(int w_param, NMHDR* l_param) {
1181 return message_handler_->OnNotify(w_param, l_param); 887 return message_handler_->OnNotify(w_param, l_param);
1182 } 888 }
1183 889
1184 void NativeWidgetWin::OnPaint(HDC dc) { 890 void NativeWidgetWin::OnPaint(HDC dc) {
1185 RECT dirty_rect; 891 message_handler_->OnPaint(dc);
1186 // Try to paint accelerated first.
1187 if (GetUpdateRect(hwnd(), &dirty_rect, FALSE) &&
1188 !IsRectEmpty(&dirty_rect)) {
1189 if (delegate_->OnNativeWidgetPaintAccelerated(
1190 gfx::Rect(dirty_rect))) {
1191 ValidateRect(hwnd(), NULL);
1192 } else {
1193 scoped_ptr<gfx::CanvasPaint> canvas(
1194 gfx::CanvasPaint::CreateCanvasPaint(hwnd()));
1195 delegate_->OnNativeWidgetPaint(canvas->AsCanvas());
1196 }
1197 } else {
1198 // TODO(msw): Find a better solution for this crbug.com/93530 workaround.
1199 // Some scenarios otherwise fail to validate minimized app/popup windows.
1200 ValidateRect(hwnd(), NULL);
1201 }
1202 } 892 }
1203 893
1204 LRESULT NativeWidgetWin::OnPowerBroadcast(DWORD power_event, DWORD data) { 894 LRESULT NativeWidgetWin::OnPowerBroadcast(DWORD power_event, DWORD data) {
1205 return message_handler_->OnPowerBroadcast(power_event, data); 895 return message_handler_->OnPowerBroadcast(power_event, data);
1206 } 896 }
1207 897
1208 LRESULT NativeWidgetWin::OnReflectedMessage(UINT msg, 898 LRESULT NativeWidgetWin::OnReflectedMessage(UINT msg,
1209 WPARAM w_param, 899 WPARAM w_param,
1210 LPARAM l_param) { 900 LPARAM l_param) {
1211 return message_handler_->OnReflectedMessage(msg, w_param, l_param); 901 return message_handler_->OnReflectedMessage(msg, w_param, l_param);
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
1347 bool NativeWidgetWin::GetClientAreaInsets(gfx::Insets* insets) const { 1037 bool NativeWidgetWin::GetClientAreaInsets(gfx::Insets* insets) const {
1348 return false; 1038 return false;
1349 } 1039 }
1350 1040
1351 void NativeWidgetWin::GetMinMaxSize(gfx::Size* min_size, 1041 void NativeWidgetWin::GetMinMaxSize(gfx::Size* min_size,
1352 gfx::Size* max_size) const { 1042 gfx::Size* max_size) const {
1353 *min_size = delegate_->GetMinimumSize(); 1043 *min_size = delegate_->GetMinimumSize();
1354 *max_size = delegate_->GetMaximumSize(); 1044 *max_size = delegate_->GetMaximumSize();
1355 } 1045 }
1356 1046
1047 gfx::Size NativeWidgetWin::GetRootViewSize() const {
1048 return GetWidget()->GetRootView()->size();
1049 }
1050
1357 void NativeWidgetWin::ResetWindowControls() { 1051 void NativeWidgetWin::ResetWindowControls() {
1358 GetWidget()->non_client_view()->ResetWindowControls(); 1052 GetWidget()->non_client_view()->ResetWindowControls();
1359 } 1053 }
1360 1054
1055 void NativeWidgetWin::UpdateFrame() {
1056 GetWidget()->non_client_view()->UpdateFrame();
1057 }
1058
1059 void NativeWidgetWin::PaintLayeredWindow(gfx::Canvas* canvas) {
1060 GetWidget()->GetRootView()->Paint(canvas);
1061 }
1062
1361 InputMethod* NativeWidgetWin::GetInputMethod() { 1063 InputMethod* NativeWidgetWin::GetInputMethod() {
1362 return GetWidget()->GetInputMethodDirect(); 1064 return GetWidget()->GetInputMethodDirect();
1363 } 1065 }
1364 1066
1365 gfx::NativeViewAccessible NativeWidgetWin::GetNativeViewAccessible() { 1067 gfx::NativeViewAccessible NativeWidgetWin::GetNativeViewAccessible() {
1366 return GetWidget()->GetRootView()->GetNativeViewAccessible(); 1068 return GetWidget()->GetRootView()->GetNativeViewAccessible();
1367 } 1069 }
1368 1070
1369 void NativeWidgetWin::HandleAppDeactivated() { 1071 void NativeWidgetWin::HandleAppDeactivated() {
1370 // Another application was activated, we should reset any state that 1072 // Another application was activated, we should reset any state that
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
1472 void NativeWidgetWin::HandleWorkAreaChanged() { 1174 void NativeWidgetWin::HandleWorkAreaChanged() {
1473 GetWidget()->widget_delegate()->OnWorkAreaChanged(); 1175 GetWidget()->widget_delegate()->OnWorkAreaChanged();
1474 } 1176 }
1475 1177
1476 void NativeWidgetWin::HandleVisibilityChanged(bool visible) { 1178 void NativeWidgetWin::HandleVisibilityChanged(bool visible) {
1477 delegate_->OnNativeWidgetVisibilityChanged(visible); 1179 delegate_->OnNativeWidgetVisibilityChanged(visible);
1478 } 1180 }
1479 1181
1480 void NativeWidgetWin::HandleClientSizeChanged(const gfx::Size& new_size) { 1182 void NativeWidgetWin::HandleClientSizeChanged(const gfx::Size& new_size) {
1481 delegate_->OnNativeWidgetSizeChanged(new_size); 1183 delegate_->OnNativeWidgetSizeChanged(new_size);
1482 if (use_layered_buffer_) {
1483 layered_window_contents_.reset(
1484 new gfx::Canvas(new_size, ui::SCALE_FACTOR_100P, false));
1485 }
1486 } 1184 }
1487 1185
1488 void NativeWidgetWin::HandleNativeFocus(HWND last_focused_window) { 1186 void NativeWidgetWin::HandleNativeFocus(HWND last_focused_window) {
1489 delegate_->OnNativeFocus(last_focused_window); 1187 delegate_->OnNativeFocus(last_focused_window);
1490 } 1188 }
1491 1189
1492 void NativeWidgetWin::HandleNativeBlur(HWND focused_window) { 1190 void NativeWidgetWin::HandleNativeBlur(HWND focused_window) {
1493 delegate_->OnNativeBlur(focused_window); 1191 delegate_->OnNativeBlur(focused_window);
1494 } 1192 }
1495 1193
1496 bool NativeWidgetWin::HandleMouseEvent(const ui::MouseEvent& event) { 1194 bool NativeWidgetWin::HandleMouseEvent(const ui::MouseEvent& event) {
1497 return delegate_->OnMouseEvent(event); 1195 return delegate_->OnMouseEvent(event);
1498 } 1196 }
1499 1197
1500 bool NativeWidgetWin::HandleKeyEvent(const ui::KeyEvent& event) { 1198 bool NativeWidgetWin::HandleKeyEvent(const ui::KeyEvent& event) {
1501 return delegate_->OnKeyEvent(event); 1199 return delegate_->OnKeyEvent(event);
1502 } 1200 }
1503 1201
1202 bool NativeWidgetWin::HandlePaintAccelerated(const gfx::Rect& invalid_rect) {
1203 return delegate_->OnNativeWidgetPaintAccelerated(gfx::Rect(invalid_rect));
1204 }
1205
1206 void NativeWidgetWin::HandlePaint(gfx::Canvas* canvas) {
1207 delegate_->OnNativeWidgetPaint(canvas);
1208 }
1209
1504 void NativeWidgetWin::HandleScreenReaderDetected() { 1210 void NativeWidgetWin::HandleScreenReaderDetected() {
1505 // TODO(beng): just consolidate this with OnScreenReaderDetected. 1211 // TODO(beng): just consolidate this with OnScreenReaderDetected.
1506 OnScreenReaderDetected(); 1212 OnScreenReaderDetected();
1507 } 1213 }
1508 1214
1509 bool NativeWidgetWin::HandleTooltipNotify(int w_param, 1215 bool NativeWidgetWin::HandleTooltipNotify(int w_param,
1510 NMHDR* l_param, 1216 NMHDR* l_param,
1511 LRESULT* l_result) { 1217 LRESULT* l_result) {
1512 // We can be sent this message before the tooltip manager is created, if a 1218 // We can be sent this message before the tooltip manager is created, if a
1513 // subclass overrides OnCreate and creates some kind of Windows control there 1219 // subclass overrides OnCreate and creates some kind of Windows control there
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after
1656 } 1362 }
1657 1363
1658 set_initial_class_style(class_style); 1364 set_initial_class_style(class_style);
1659 set_window_style(window_style() | style); 1365 set_window_style(window_style() | style);
1660 set_window_ex_style(window_ex_style() | ex_style); 1366 set_window_ex_style(window_ex_style() | ex_style);
1661 1367
1662 has_non_client_view_ = Widget::RequiresNonClientView(params.type); 1368 has_non_client_view_ = Widget::RequiresNonClientView(params.type);
1663 message_handler_->set_remove_standard_frame(params.remove_standard_frame); 1369 message_handler_->set_remove_standard_frame(params.remove_standard_frame);
1664 } 1370 }
1665 1371
1666 void NativeWidgetWin::RedrawInvalidRect() {
1667 if (!use_layered_buffer_) {
1668 RECT r = { 0, 0, 0, 0 };
1669 if (GetUpdateRect(hwnd(), &r, FALSE) && !IsRectEmpty(&r)) {
1670 RedrawWindow(hwnd(), &r, NULL,
1671 RDW_INVALIDATE | RDW_UPDATENOW | RDW_NOCHILDREN);
1672 }
1673 }
1674 }
1675
1676 void NativeWidgetWin::RedrawLayeredWindowContents() {
1677 if (invalid_rect_.IsEmpty())
1678 return;
1679
1680 // We need to clip to the dirty rect ourselves.
1681 layered_window_contents_->sk_canvas()->save(SkCanvas::kClip_SaveFlag);
1682 layered_window_contents_->ClipRect(invalid_rect_);
1683 GetWidget()->GetRootView()->Paint(layered_window_contents_.get());
1684 layered_window_contents_->sk_canvas()->restore();
1685
1686 RECT wr;
1687 GetWindowRect(&wr);
1688 SIZE size = {wr.right - wr.left, wr.bottom - wr.top};
1689 POINT position = {wr.left, wr.top};
1690 HDC dib_dc = skia::BeginPlatformPaint(layered_window_contents_->sk_canvas());
1691 POINT zero = {0, 0};
1692 BLENDFUNCTION blend = {AC_SRC_OVER, 0, layered_alpha_, AC_SRC_ALPHA};
1693 UpdateLayeredWindow(hwnd(), NULL, &position, &size, dib_dc, &zero,
1694 RGB(0xFF, 0xFF, 0xFF), &blend, ULW_ALPHA);
1695 invalid_rect_.SetRect(0, 0, 0, 0);
1696 skia::EndPlatformPaint(layered_window_contents_->sk_canvas());
1697 }
1698
1699 bool NativeWidgetWin::WidgetSizeIsClientSize() const { 1372 bool NativeWidgetWin::WidgetSizeIsClientSize() const {
1700 const Widget* widget = GetWidget()->GetTopLevelWidget(); 1373 const Widget* widget = GetWidget()->GetTopLevelWidget();
1701 return IsZoomed() || (widget && widget->ShouldUseNativeFrame()); 1374 return IsZoomed() || (widget && widget->ShouldUseNativeFrame());
1702 } 1375 }
1703 1376
1704 void NativeWidgetWin::RestoreEnabledIfNecessary() { 1377 void NativeWidgetWin::RestoreEnabledIfNecessary() {
1705 if (delegate_->IsModal() && !restored_enabled_) { 1378 if (delegate_->IsModal() && !restored_enabled_) {
1706 restored_enabled_ = true; 1379 restored_enabled_ = true;
1707 // If we were run modally, we need to undo the disabled-ness we inflicted on 1380 // If we were run modally, we need to undo the disabled-ness we inflicted on
1708 // the owner's parent hierarchy. 1381 // the owner's parent hierarchy.
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after
1877 // static 1550 // static
1878 bool NativeWidgetPrivate::IsTouchDown() { 1551 bool NativeWidgetPrivate::IsTouchDown() {
1879 // This currently isn't necessary because we're not generating touch events on 1552 // This currently isn't necessary because we're not generating touch events on
1880 // windows. When we do, this will need to be updated. 1553 // windows. When we do, this will need to be updated.
1881 return false; 1554 return false;
1882 } 1555 }
1883 1556
1884 } // namespace internal 1557 } // namespace internal
1885 1558
1886 } // namespace views 1559 } // namespace views
OLDNEW
« no previous file with comments | « ui/views/widget/native_widget_win.h ('k') | ui/views/win/DEPS » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698