OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 "views/widget/native_widget_win.h" | 5 #include "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 362 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
373 NativeWidgetWin::NativeWidgetWin(internal::NativeWidgetDelegate* delegate) | 373 NativeWidgetWin::NativeWidgetWin(internal::NativeWidgetDelegate* delegate) |
374 : delegate_(delegate), | 374 : delegate_(delegate), |
375 ALLOW_THIS_IN_INITIALIZER_LIST(close_widget_factory_(this)), | 375 ALLOW_THIS_IN_INITIALIZER_LIST(close_widget_factory_(this)), |
376 active_mouse_tracking_flags_(0), | 376 active_mouse_tracking_flags_(0), |
377 use_layered_buffer_(false), | 377 use_layered_buffer_(false), |
378 layered_alpha_(255), | 378 layered_alpha_(255), |
379 ALLOW_THIS_IN_INITIALIZER_LIST(paint_layered_window_factory_(this)), | 379 ALLOW_THIS_IN_INITIALIZER_LIST(paint_layered_window_factory_(this)), |
380 ownership_(Widget::InitParams::NATIVE_WIDGET_OWNS_WIDGET), | 380 ownership_(Widget::InitParams::NATIVE_WIDGET_OWNS_WIDGET), |
381 can_update_layered_window_(true), | 381 can_update_layered_window_(true), |
382 restore_focus_when_enabled_(false), | 382 restore_focus_when_enabled_(false), |
383 accessibility_view_events_index_(-1), | |
384 accessibility_view_events_(kMaxAccessibilityViewEvents), | |
385 previous_cursor_(NULL), | 383 previous_cursor_(NULL), |
386 fullscreen_(false), | 384 fullscreen_(false), |
387 force_hidden_count_(0), | 385 force_hidden_count_(0), |
388 lock_updates_count_(0), | 386 lock_updates_count_(0), |
389 saved_window_style_(0), | 387 saved_window_style_(0), |
390 ignore_window_pos_changes_(false), | 388 ignore_window_pos_changes_(false), |
391 ALLOW_THIS_IN_INITIALIZER_LIST(ignore_pos_changes_factory_(this)), | 389 ALLOW_THIS_IN_INITIALIZER_LIST(ignore_pos_changes_factory_(this)), |
392 last_monitor_(NULL), | 390 last_monitor_(NULL), |
393 is_right_mouse_pressed_on_caption_(false), | 391 is_right_mouse_pressed_on_caption_(false), |
394 restored_enabled_(false), | 392 restored_enabled_(false), |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
440 // We need to explicitly activate the window if we've been shown with a state | 438 // We need to explicitly activate the window if we've been shown with a state |
441 // that should activate, because if we're opened from a desktop shortcut while | 439 // that should activate, because if we're opened from a desktop shortcut while |
442 // an existing window is already running it doesn't seem to be enough to use | 440 // an existing window is already running it doesn't seem to be enough to use |
443 // one of these flags to activate the window. | 441 // one of these flags to activate the window. |
444 if (show_state == SW_SHOWNORMAL || show_state == SW_SHOWMAXIMIZED) | 442 if (show_state == SW_SHOWNORMAL || show_state == SW_SHOWMAXIMIZED) |
445 Activate(); | 443 Activate(); |
446 | 444 |
447 SetInitialFocus(); | 445 SetInitialFocus(); |
448 } | 446 } |
449 | 447 |
450 View* NativeWidgetWin::GetAccessibilityViewEventAt(int id) { | 448 View* NativeWidgetWin::GetViewByAccessibleId(long child_id) { |
451 // Convert from MSAA child id. | 449 // The IAccessible2 unique ID is the negation of the child ID; |
452 id = -(id + 1); | 450 // see the comments in SendNativeAccessibilityEvent for details. |
453 DCHECK(id >= 0 && id < kMaxAccessibilityViewEvents); | 451 return FindViewByIA2UniqueId(-child_id, GetWidget()->GetRootView()); |
454 return accessibility_view_events_[id]; | |
455 } | |
456 | |
457 int NativeWidgetWin::AddAccessibilityViewEvent(View* view) { | |
458 accessibility_view_events_index_ = | |
459 (accessibility_view_events_index_ + 1) % kMaxAccessibilityViewEvents; | |
460 accessibility_view_events_[accessibility_view_events_index_] = view; | |
461 | |
462 // Convert to MSAA child id. | |
463 return -(accessibility_view_events_index_ + 1); | |
464 } | |
465 | |
466 void NativeWidgetWin::ClearAccessibilityViewEvent(View* view) { | |
467 for (std::vector<View*>::iterator it = accessibility_view_events_.begin(); | |
468 it != accessibility_view_events_.end(); | |
469 ++it) { | |
470 if (*it == view) | |
471 *it = NULL; | |
472 } | |
473 } | 452 } |
474 | 453 |
475 void NativeWidgetWin::PushForceHidden() { | 454 void NativeWidgetWin::PushForceHidden() { |
476 if (force_hidden_count_++ == 0) | 455 if (force_hidden_count_++ == 0) |
477 Hide(); | 456 Hide(); |
478 } | 457 } |
479 | 458 |
480 void NativeWidgetWin::PopForceHidden() { | 459 void NativeWidgetWin::PopForceHidden() { |
481 if (--force_hidden_count_ <= 0) { | 460 if (--force_hidden_count_ <= 0) { |
482 force_hidden_count_ = 0; | 461 force_hidden_count_ = 0; |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
584 gfx::Point* offset, | 563 gfx::Point* offset, |
585 ui::Layer** layer_parent) { | 564 ui::Layer** layer_parent) { |
586 } | 565 } |
587 | 566 |
588 void NativeWidgetWin::ReorderLayers() { | 567 void NativeWidgetWin::ReorderLayers() { |
589 } | 568 } |
590 | 569 |
591 void NativeWidgetWin::ViewRemoved(View* view) { | 570 void NativeWidgetWin::ViewRemoved(View* view) { |
592 if (drop_target_.get()) | 571 if (drop_target_.get()) |
593 drop_target_->ResetTargetViewIfEquals(view); | 572 drop_target_->ResetTargetViewIfEquals(view); |
594 | |
595 ClearAccessibilityViewEvent(view); | |
596 } | 573 } |
597 | 574 |
598 void NativeWidgetWin::SetNativeWindowProperty(const char* name, void* value) { | 575 void NativeWidgetWin::SetNativeWindowProperty(const char* name, void* value) { |
599 // Remove the existing property (if any). | 576 // Remove the existing property (if any). |
600 for (ViewProps::iterator i = props_.begin(); i != props_.end(); ++i) { | 577 for (ViewProps::iterator i = props_.begin(); i != props_.end(); ++i) { |
601 if ((*i)->Key() == name) { | 578 if ((*i)->Key() == name) { |
602 props_.erase(i); | 579 props_.erase(i); |
603 break; | 580 break; |
604 } | 581 } |
605 } | 582 } |
(...skipping 10 matching lines...) Expand all Loading... |
616 return tooltip_manager_.get(); | 593 return tooltip_manager_.get(); |
617 } | 594 } |
618 | 595 |
619 bool NativeWidgetWin::IsScreenReaderActive() const { | 596 bool NativeWidgetWin::IsScreenReaderActive() const { |
620 return screen_reader_active_; | 597 return screen_reader_active_; |
621 } | 598 } |
622 | 599 |
623 void NativeWidgetWin::SendNativeAccessibilityEvent( | 600 void NativeWidgetWin::SendNativeAccessibilityEvent( |
624 View* view, | 601 View* view, |
625 ui::AccessibilityTypes::Event event_type) { | 602 ui::AccessibilityTypes::Event event_type) { |
626 // Now call the Windows-specific method to notify MSAA clients of this | 603 DWORD native_event = NativeViewAccessibilityWin::MSAAEvent(event_type); |
627 // event. The widget gives us a temporary unique child ID to associate | 604 gfx::NativeView native_view = this->GetNativeView(); |
628 // with this view so that clients can call get_accChild in | 605 |
629 // NativeViewAccessibilityWin to retrieve the IAccessible associated | 606 // Get the unique ID from the view's IAccessible2 interface. |
630 // with this view. | 607 IAccessible* accessible = view->GetNativeViewAccessible(); |
631 int child_id = AddAccessibilityViewEvent(view); | 608 IAccessible2* accessible2 = NULL; |
632 ::NotifyWinEvent(NativeViewAccessibilityWin::MSAAEvent(event_type), | 609 HRESULT hr = accessible->QueryInterface( |
633 GetNativeView(), OBJID_CLIENT, child_id); | 610 IID_IAccessible2, reinterpret_cast<void**>(&accessible2)); |
| 611 if (hr != S_OK) { |
| 612 // If this is reached, you're probably trying to fire a notification on a |
| 613 // views::NativeViewHost that has only a default IAccessible. You have to |
| 614 // either call ::NotifyWinEvent directly, or override |
| 615 // GetNativeViewAccessible for that view. |
| 616 NOTREACHED(); |
| 617 return; |
| 618 } |
| 619 long unique_id; |
| 620 hr = accessible2->get_uniqueID(&unique_id); |
| 621 DCHECK_EQ(hr, S_OK); |
| 622 |
| 623 // Send the negation of the unique id as the child id parameter to |
| 624 // NotifyWinEvent. The client will call get_accChild on the top-level |
| 625 // NativeViewAccessibilityWin object, where positive child ids are |
| 626 // interpreted as 1-based child indices, and negative child ids are |
| 627 // interpreted as unique ids. |
| 628 ::NotifyWinEvent(native_event, native_view, OBJID_CLIENT, -unique_id); |
634 } | 629 } |
635 | 630 |
636 void NativeWidgetWin::SetMouseCapture() { | 631 void NativeWidgetWin::SetMouseCapture() { |
637 DCHECK(!HasMouseCapture()); | 632 DCHECK(!HasMouseCapture()); |
638 SetCapture(hwnd()); | 633 SetCapture(hwnd()); |
639 } | 634 } |
640 | 635 |
641 void NativeWidgetWin::ReleaseMouseCapture() { | 636 void NativeWidgetWin::ReleaseMouseCapture() { |
642 ReleaseCapture(); | 637 ReleaseCapture(); |
643 } | 638 } |
(...skipping 1814 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2458 ::EnableWindow(start, TRUE); | 2453 ::EnableWindow(start, TRUE); |
2459 start = ::GetParent(start); | 2454 start = ::GetParent(start); |
2460 } | 2455 } |
2461 } | 2456 } |
2462 } | 2457 } |
2463 | 2458 |
2464 void NativeWidgetWin::DispatchKeyEventPostIME(const KeyEvent& key) { | 2459 void NativeWidgetWin::DispatchKeyEventPostIME(const KeyEvent& key) { |
2465 SetMsgHandled(delegate_->OnKeyEvent(key)); | 2460 SetMsgHandled(delegate_->OnKeyEvent(key)); |
2466 } | 2461 } |
2467 | 2462 |
| 2463 View* NativeWidgetWin::FindViewByIA2UniqueId(long id, View* view) { |
| 2464 IAccessible* accessible = view->GetNativeViewAccessible(); |
| 2465 IAccessible2* accessible2 = NULL; |
| 2466 if (S_OK == accessible->QueryInterface( |
| 2467 IID_IAccessible2, reinterpret_cast<void**>(&accessible2))) { |
| 2468 long unique_id; |
| 2469 if (S_OK == accessible2->get_uniqueID(&unique_id) && id == unique_id) |
| 2470 return view; |
| 2471 } |
| 2472 |
| 2473 for (int i = 0; i < view->child_count(); i++) { |
| 2474 View* result = FindViewByIA2UniqueId(id, view->child_at(i)); |
| 2475 if (result) |
| 2476 return result; |
| 2477 } |
| 2478 |
| 2479 return NULL; |
| 2480 } |
| 2481 |
2468 //////////////////////////////////////////////////////////////////////////////// | 2482 //////////////////////////////////////////////////////////////////////////////// |
2469 // Widget, public: | 2483 // Widget, public: |
2470 | 2484 |
2471 // static | 2485 // static |
2472 void Widget::NotifyLocaleChanged() { | 2486 void Widget::NotifyLocaleChanged() { |
2473 NOTIMPLEMENTED(); | 2487 NOTIMPLEMENTED(); |
2474 } | 2488 } |
2475 | 2489 |
2476 namespace { | 2490 namespace { |
2477 BOOL CALLBACK WindowCallbackProc(HWND hwnd, LPARAM lParam) { | 2491 BOOL CALLBACK WindowCallbackProc(HWND hwnd, LPARAM lParam) { |
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2625 return (GetKeyState(VK_LBUTTON) & 0x80) || | 2639 return (GetKeyState(VK_LBUTTON) & 0x80) || |
2626 (GetKeyState(VK_RBUTTON) & 0x80) || | 2640 (GetKeyState(VK_RBUTTON) & 0x80) || |
2627 (GetKeyState(VK_MBUTTON) & 0x80) || | 2641 (GetKeyState(VK_MBUTTON) & 0x80) || |
2628 (GetKeyState(VK_XBUTTON1) & 0x80) || | 2642 (GetKeyState(VK_XBUTTON1) & 0x80) || |
2629 (GetKeyState(VK_XBUTTON2) & 0x80); | 2643 (GetKeyState(VK_XBUTTON2) & 0x80); |
2630 } | 2644 } |
2631 | 2645 |
2632 } // namespace internal | 2646 } // namespace internal |
2633 | 2647 |
2634 } // namespace views | 2648 } // namespace views |
OLD | NEW |