diff options
author | ben@chromium.org <ben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-04-01 22:28:44 +0000 |
---|---|---|
committer | ben@chromium.org <ben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-04-01 22:28:44 +0000 |
commit | 449a1685341fb38c088bb664c88b536a48c2066d (patch) | |
tree | 84df488c8c789f67ff2827aef339b4926025f5ef | |
parent | 14d4f99f31f9365a20d5726b44bcb3e53b5b65f9 (diff) | |
download | chromium_src-449a1685341fb38c088bb664c88b536a48c2066d.zip chromium_src-449a1685341fb38c088bb664c88b536a48c2066d.tar.gz chromium_src-449a1685341fb38c088bb664c88b536a48c2066d.tar.bz2 |
Consolidate cross platform logic into MenuHost.
BUG=72040
TEST=none
Review URL: http://codereview.chromium.org/6690054
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@80232 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | views/controls/menu/menu_controller.cc | 4 | ||||
-rw-r--r-- | views/controls/menu/menu_host.cc | 77 | ||||
-rw-r--r-- | views/controls/menu/menu_host.h | 21 | ||||
-rw-r--r-- | views/controls/menu/menu_host_gtk.cc | 164 | ||||
-rw-r--r-- | views/controls/menu/menu_host_gtk.h | 33 | ||||
-rw-r--r-- | views/controls/menu/menu_host_win.cc | 99 | ||||
-rw-r--r-- | views/controls/menu/menu_host_win.h | 32 | ||||
-rw-r--r-- | views/controls/menu/native_menu_host.h | 37 | ||||
-rw-r--r-- | views/controls/menu/native_menu_host_delegate.h | 13 | ||||
-rw-r--r-- | views/controls/menu/submenu_view.cc | 4 | ||||
-rw-r--r-- | views/controls/menu/submenu_view.h | 3 | ||||
-rw-r--r-- | views/widget/native_widget.h | 5 | ||||
-rw-r--r-- | views/widget/widget.cc | 4 | ||||
-rw-r--r-- | views/widget/widget.h | 3 | ||||
-rw-r--r-- | views/widget/widget_gtk.cc | 42 | ||||
-rw-r--r-- | views/widget/widget_gtk.h | 4 | ||||
-rw-r--r-- | views/widget/widget_win.cc | 108 | ||||
-rw-r--r-- | views/widget/widget_win.h | 4 |
18 files changed, 288 insertions, 369 deletions
diff --git a/views/controls/menu/menu_controller.cc b/views/controls/menu/menu_controller.cc index 59ba744..6327684 100644 --- a/views/controls/menu/menu_controller.cc +++ b/views/controls/menu/menu_controller.cc @@ -1697,8 +1697,8 @@ void MenuController::RepostEvent(SubmenuView* source, SubmenuView* submenu = state_.item->GetRootMenuItem()->GetSubmenu(); submenu->ReleaseCapture(); - if (submenu->native_window() && submenu->native_window() && - GetWindowThreadProcessId(submenu->native_window(), NULL) != + if (submenu->GetWidget()->GetNativeView() && + GetWindowThreadProcessId(submenu->GetWidget()->GetNativeView(), NULL) != GetWindowThreadProcessId(window, NULL)) { // Even though we have mouse capture, windows generates a mouse event // if the other window is in a separate thread. Don't generate an event in diff --git a/views/controls/menu/menu_host.cc b/views/controls/menu/menu_host.cc index 30ba412..ce53f92 100644 --- a/views/controls/menu/menu_host.cc +++ b/views/controls/menu/menu_host.cc @@ -3,7 +3,14 @@ // found in the LICENSE file. #include "views/controls/menu/menu_host.h" + +#include "views/controls/menu/menu_controller.h" +#include "views/controls/menu/menu_host_root_view.h" +#include "views/controls/menu/menu_item_view.h" #include "views/controls/menu/native_menu_host.h" +#include "views/controls/menu/submenu_view.h" +#include "views/widget/native_widget.h" +#include "views/widget/widget.h" namespace views { @@ -11,7 +18,14 @@ namespace views { // MenuHost, public: MenuHost::MenuHost(SubmenuView* submenu) - : native_menu_host_(NativeMenuHost::CreateNativeMenuHost(submenu)) { + : ALLOW_THIS_IN_INITIALIZER_LIST(native_menu_host_( + NativeMenuHost::CreateNativeMenuHost(this))), + submenu_(submenu), + destroying_(false) { + Widget::CreateParams params; + params.type = Widget::CreateParams::TYPE_MENU; + params.has_dropshadow = true; + GetWidget()->SetCreateParams(params); } MenuHost::~MenuHost() { @@ -21,36 +35,77 @@ void MenuHost::InitMenuHost(gfx::NativeWindow parent, const gfx::Rect& bounds, View* contents_view, bool do_capture) { - native_menu_host_->InitMenuHost(parent, bounds, contents_view, do_capture); + native_menu_host_->InitMenuHost(parent, bounds); + GetWidget()->SetContentsView(contents_view); + ShowMenuHost(do_capture); } bool MenuHost::IsMenuHostVisible() { - return native_menu_host_->IsMenuHostVisible(); + return GetWidget()->IsVisible(); } void MenuHost::ShowMenuHost(bool do_capture) { - native_menu_host_->ShowMenuHost(do_capture); + GetWidget()->Show(); + if (do_capture) + native_menu_host_->StartCapturing(); } void MenuHost::HideMenuHost() { - native_menu_host_->HideMenuHost(); + ReleaseMenuHostCapture(); + GetWidget()->Hide(); } void MenuHost::DestroyMenuHost() { - native_menu_host_->DestroyMenuHost(); - delete this; + HideMenuHost(); + destroying_ = true; + GetWidget()->Close(); } void MenuHost::SetMenuHostBounds(const gfx::Rect& bounds) { - native_menu_host_->SetMenuHostBounds(bounds); + GetWidget()->SetBounds(bounds); } void MenuHost::ReleaseMenuHostCapture() { - native_menu_host_->ReleaseMenuHostCapture(); + if (GetWidget()->native_widget()->HasMouseCapture()) + GetWidget()->native_widget()->ReleaseMouseCapture(); +} + +Widget* MenuHost::GetWidget() { + return native_menu_host_->AsNativeWidget()->GetWidget(); +} + +NativeWidget* MenuHost::GetNativeWidget() { + return native_menu_host_->AsNativeWidget(); +} + +//////////////////////////////////////////////////////////////////////////////// +// MenuHost, internal::NativeMenuHostDelegate implementation: + +void MenuHost::OnNativeMenuHostDestroy() { + if (!destroying_) { + // We weren't explicitly told to destroy ourselves, which means the menu was + // deleted out from under us (the window we're parented to was closed). Tell + // the SubmenuView to drop references to us. + submenu_->MenuHostDestroyed(); + } +} + +void MenuHost::OnNativeMenuHostCancelCapture() { + if (destroying_) + return; + MenuController* menu_controller = + submenu_->GetMenuItem()->GetMenuController(); + if (menu_controller && + !menu_controller->drag_in_progress()) + menu_controller->CancelAll(); +} + +RootView* MenuHost::CreateRootView() { + return new MenuHostRootView(GetWidget(), submenu_); } -gfx::NativeWindow MenuHost::GetMenuHostWindow() { - return native_menu_host_->GetMenuHostWindow(); +bool MenuHost::ShouldReleaseCaptureOnMouseRelease() const { + return false; } } // namespace views diff --git a/views/controls/menu/menu_host.h b/views/controls/menu/menu_host.h index bc7e5b6..41ecf8e 100644 --- a/views/controls/menu/menu_host.h +++ b/views/controls/menu/menu_host.h @@ -6,14 +6,18 @@ #define VIEWS_CONTROLS_MENU_MENU_HOST_H_ #pragma once +#include "base/compiler_specific.h" #include "ui/gfx/native_widget_types.h" #include "ui/gfx/rect.h" +#include "views/controls/menu/native_menu_host_delegate.h" namespace views { class NativeMenuHost; +class NativeWidget; class SubmenuView; class View; +class Widget; // SubmenuView uses a MenuHost to house the SubmenuView. MenuHost typically // extends the native Widget type, but is defined here for clarity of what @@ -24,7 +28,7 @@ class View; // OS destroys the widget out from under us, in which case |MenuHostDestroyed| // is invoked back on the SubmenuView and the SubmenuView then drops references // to the MenuHost. -class MenuHost { +class MenuHost : public internal::NativeMenuHostDelegate { public: explicit MenuHost(SubmenuView* submenu); virtual ~MenuHost(); @@ -57,9 +61,24 @@ class MenuHost { // Returns the native window of the MenuHost. gfx::NativeWindow GetMenuHostWindow(); + Widget* GetWidget(); + NativeWidget* GetNativeWidget(); + private: + // Overridden from NativeMenuHostDelegate: + virtual void OnNativeMenuHostDestroy() OVERRIDE; + virtual void OnNativeMenuHostCancelCapture() OVERRIDE; + virtual RootView* CreateRootView() OVERRIDE; + virtual bool ShouldReleaseCaptureOnMouseRelease() const OVERRIDE; + NativeMenuHost* native_menu_host_; + // The view we contain. + SubmenuView* submenu_; + + // If true, DestroyMenuHost has been invoked. + bool destroying_; + DISALLOW_COPY_AND_ASSIGN(MenuHost); }; diff --git a/views/controls/menu/menu_host_gtk.cc b/views/controls/menu/menu_host_gtk.cc index 0f4dfc7..fed765d 100644 --- a/views/controls/menu/menu_host_gtk.cc +++ b/views/controls/menu/menu_host_gtk.cc @@ -11,10 +11,7 @@ #include <X11/extensions/XInput2.h> #endif -#include "views/controls/menu/menu_controller.h" -#include "views/controls/menu/menu_host_root_view.h" -#include "views/controls/menu/menu_item_view.h" -#include "views/controls/menu/submenu_view.h" +#include "views/controls/menu/native_menu_host_delegate.h" #if defined(HAVE_XINPUT2) && defined(TOUCH_UI) #include "views/touchui/touch_factory.h" @@ -25,15 +22,10 @@ namespace views { //////////////////////////////////////////////////////////////////////////////// // MenuHostGtk, public: -MenuHostGtk::MenuHostGtk(SubmenuView* submenu) +MenuHostGtk::MenuHostGtk(internal::NativeMenuHostDelegate* delegate) : WidgetGtk(WidgetGtk::TYPE_POPUP), - destroying_(false), - submenu_(submenu), - did_input_grab_(false) { - CreateParams params; - params.type = CreateParams::TYPE_MENU; - params.has_dropshadow = true; - SetCreateParams(params); + did_input_grab_(false), + delegate_(delegate) { } MenuHostGtk::~MenuHostGtk() { @@ -43,68 +35,70 @@ MenuHostGtk::~MenuHostGtk() { // MenuHostGtk, NativeMenuHost implementation: void MenuHostGtk::InitMenuHost(gfx::NativeWindow parent, - const gfx::Rect& bounds, - View* contents_view, - bool do_capture) { + const gfx::Rect& bounds) { make_transient_to_parent(); WidgetGtk::Init(GTK_WIDGET(parent), bounds); // Make sure we get destroyed when the parent is destroyed. gtk_window_set_destroy_with_parent(GTK_WINDOW(GetNativeView()), TRUE); gtk_window_set_type_hint(GTK_WINDOW(GetNativeView()), GDK_WINDOW_TYPE_HINT_MENU); - SetContentsView(contents_view); - ShowMenuHost(do_capture); } -bool MenuHostGtk::IsMenuHostVisible() { - return IsVisible(); -} +void MenuHostGtk::StartCapturing() { + DCHECK(!did_input_grab_); -void MenuHostGtk::ShowMenuHost(bool do_capture) { - WidgetGtk::Show(); - if (do_capture) - DoCapture(); -} + // Release the current grab. + GtkWidget* current_grab_window = gtk_grab_get_current(); + if (current_grab_window) + gtk_grab_remove(current_grab_window); -void MenuHostGtk::HideMenuHost() { - // Make sure we release capture before hiding. - ReleaseMenuHostCapture(); + // Make sure all app mouse/keyboard events are targeted at us only. + SetMouseCapture(); - WidgetGtk::Hide(); -} + // And do a grab. NOTE: we do this to ensure we get mouse/keyboard + // events from other apps, a grab done with gtk_grab_add doesn't get + // events from other apps. + GdkGrabStatus pointer_grab_status = + gdk_pointer_grab(window_contents()->window, FALSE, + static_cast<GdkEventMask>( + GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | + GDK_POINTER_MOTION_MASK), + NULL, NULL, GDK_CURRENT_TIME); + GdkGrabStatus keyboard_grab_status = + gdk_keyboard_grab(window_contents()->window, FALSE, + GDK_CURRENT_TIME); -void MenuHostGtk::DestroyMenuHost() { - HideMenuHost(); - destroying_ = true; - // We use Close instead of CloseNow to delay the deletion. If this invoked - // during a key press event, gtk still generates the release event and the - // AcceleratorHandler will use the window in the event. If we destroy the - // window now, it means AcceleratorHandler attempts to use a window that has - // been destroyed. - Close(); -} + did_input_grab_ = pointer_grab_status == GDK_GRAB_SUCCESS && + keyboard_grab_status == GDK_GRAB_SUCCESS; -void MenuHostGtk::SetMenuHostBounds(const gfx::Rect& bounds) { - SetBounds(bounds); -} + DCHECK_EQ(GDK_GRAB_SUCCESS, pointer_grab_status); + DCHECK_EQ(GDK_GRAB_SUCCESS, keyboard_grab_status); + +#if defined(HAVE_XINPUT2) && defined(TOUCH_UI) + ::Window window = GDK_WINDOW_XID(window_contents()->window); + Display* display = GDK_WINDOW_XDISPLAY(window_contents()->window); + bool xi2grab = TouchFactory::GetInstance()->GrabTouchDevices(display, window); + did_input_grab_ = did_input_grab_ && xi2grab; +#endif -void MenuHostGtk::ReleaseMenuHostCapture() { - ReleaseMouseCapture(); + DCHECK(did_input_grab_); + // need keyboard grab. } -gfx::NativeWindow MenuHostGtk::GetMenuHostWindow() { - return GTK_WINDOW(GetNativeView()); +NativeWidget* MenuHostGtk::AsNativeWidget() { + return this; } //////////////////////////////////////////////////////////////////////////////// // MenuHostGtk, WidgetGtk overrides: +// TODO(beng): remove once MenuHost is-a Widget RootView* MenuHostGtk::CreateRootView() { - return new MenuHostRootView(this, submenu_); + return delegate_->CreateRootView(); } bool MenuHostGtk::ShouldReleaseCaptureOnMouseReleased() const { - return false; + return delegate_->ShouldReleaseCaptureOnMouseRelease(); } void MenuHostGtk::ReleaseMouseCapture() { @@ -121,91 +115,35 @@ void MenuHostGtk::ReleaseMouseCapture() { } void MenuHostGtk::OnDestroy(GtkWidget* object) { - if (!destroying_) { - // We weren't explicitly told to destroy ourselves, which means the menu was - // deleted out from under us (the window we're parented to was closed). Tell - // the SubmenuView to drop references to us. - submenu_->MenuHostDestroyed(); - } + delegate_->OnNativeMenuHostDestroy(); WidgetGtk::OnDestroy(object); } void MenuHostGtk::HandleXGrabBroke() { // Grab may already be release in ReleaseGrab. - if (did_input_grab_ && !destroying_) { + if (did_input_grab_) { did_input_grab_ = false; - CancelAllIfNoDrag(); + delegate_->OnNativeMenuHostCancelCapture(); } WidgetGtk::HandleXGrabBroke(); } void MenuHostGtk::HandleGtkGrabBroke() { // Grab can be broken by drag & drop, other menu or screen locker. - if (did_input_grab_ && !destroying_) { + if (did_input_grab_) { ReleaseMouseCapture(); - CancelAllIfNoDrag(); + delegate_->OnNativeMenuHostCancelCapture(); } WidgetGtk::HandleGtkGrabBroke(); } //////////////////////////////////////////////////////////////////////////////// -// MenuHostGtk, private: - -void MenuHostGtk::DoCapture() { - DCHECK(!did_input_grab_); - - // Release the current grab. - GtkWidget* current_grab_window = gtk_grab_get_current(); - if (current_grab_window) - gtk_grab_remove(current_grab_window); - - // Make sure all app mouse/keyboard events are targetted at us only. - SetMouseCapture(); - - // And do a grab. NOTE: we do this to ensure we get mouse/keyboard - // events from other apps, a grab done with gtk_grab_add doesn't get - // events from other apps. - GdkGrabStatus pointer_grab_status = - gdk_pointer_grab(window_contents()->window, FALSE, - static_cast<GdkEventMask>( - GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | - GDK_POINTER_MOTION_MASK), - NULL, NULL, GDK_CURRENT_TIME); - GdkGrabStatus keyboard_grab_status = - gdk_keyboard_grab(window_contents()->window, FALSE, - GDK_CURRENT_TIME); - - did_input_grab_ = pointer_grab_status == GDK_GRAB_SUCCESS && - keyboard_grab_status == GDK_GRAB_SUCCESS; - - DCHECK_EQ(GDK_GRAB_SUCCESS, pointer_grab_status); - DCHECK_EQ(GDK_GRAB_SUCCESS, keyboard_grab_status); - -#if defined(HAVE_XINPUT2) && defined(TOUCH_UI) - ::Window window = GDK_WINDOW_XID(window_contents()->window); - Display* display = GDK_WINDOW_XDISPLAY(window_contents()->window); - bool xi2grab = TouchFactory::GetInstance()->GrabTouchDevices(display, window); - did_input_grab_ = did_input_grab_ && xi2grab; -#endif - - DCHECK(did_input_grab_); - // need keyboard grab. -} - -void MenuHostGtk::CancelAllIfNoDrag() { - MenuController* menu_controller = - submenu_->GetMenuItem()->GetMenuController(); - if (menu_controller && - !menu_controller->drag_in_progress()) - menu_controller->CancelAll(); -} - -//////////////////////////////////////////////////////////////////////////////// // NativeMenuHost, public: // static -NativeMenuHost* NativeMenuHost::CreateNativeMenuHost(SubmenuView* submenu) { - return new MenuHostGtk(submenu); +NativeMenuHost* NativeMenuHost::CreateNativeMenuHost( + internal::NativeMenuHostDelegate* delegate) { + return new MenuHostGtk(delegate); } } // namespace views diff --git a/views/controls/menu/menu_host_gtk.h b/views/controls/menu/menu_host_gtk.h index f25d52c..403a4d0 100644 --- a/views/controls/menu/menu_host_gtk.h +++ b/views/controls/menu/menu_host_gtk.h @@ -11,29 +11,23 @@ #include "views/widget/widget_gtk.h" namespace views { - -class SubmenuView; +namespace internal { +class NativeMenuHostDelegate; +} // NativeMenuHost implementation for Gtk. class MenuHostGtk : public WidgetGtk, public NativeMenuHost { public: - explicit MenuHostGtk(SubmenuView* submenu); + explicit MenuHostGtk(internal::NativeMenuHostDelegate* delegate); virtual ~MenuHostGtk(); private: // Overridden from NativeMenuHost: virtual void InitMenuHost(gfx::NativeWindow parent, - const gfx::Rect& bounds, - View* contents_view, - bool do_capture) OVERRIDE; - virtual bool IsMenuHostVisible() OVERRIDE; - virtual void ShowMenuHost(bool do_capture) OVERRIDE; - virtual void HideMenuHost() OVERRIDE; - virtual void DestroyMenuHost() OVERRIDE; - virtual void SetMenuHostBounds(const gfx::Rect& bounds) OVERRIDE; - virtual void ReleaseMenuHostCapture() OVERRIDE; - virtual gfx::NativeWindow GetMenuHostWindow() OVERRIDE; + const gfx::Rect& bounds) OVERRIDE; + virtual void StartCapturing() OVERRIDE; + virtual NativeWidget* AsNativeWidget() OVERRIDE; // Overridden from WidgetGtk: virtual RootView* CreateRootView() OVERRIDE; @@ -43,20 +37,11 @@ class MenuHostGtk : public WidgetGtk, virtual void HandleGtkGrabBroke() OVERRIDE; virtual void HandleXGrabBroke() OVERRIDE; - void DoCapture(); - - // Cancel all menus unless drag is in progress. - void CancelAllIfNoDrag(); - - // If true, DestroyMenuHost has been invoked. - bool destroying_; - - // The view we contain. - SubmenuView* submenu_; - // Have we done input grab? bool did_input_grab_; + scoped_ptr<internal::NativeMenuHostDelegate> delegate_; + DISALLOW_COPY_AND_ASSIGN(MenuHostGtk); }; diff --git a/views/controls/menu/menu_host_win.cc b/views/controls/menu/menu_host_win.cc index 0392a34..79387e4 100644 --- a/views/controls/menu/menu_host_win.cc +++ b/views/controls/menu/menu_host_win.cc @@ -4,25 +4,15 @@ #include "views/controls/menu/menu_host_win.h" -#include "base/win/windows_version.h" -#include "views/controls/menu/menu_controller.h" -#include "views/controls/menu/menu_host_root_view.h" -#include "views/controls/menu/menu_item_view.h" -#include "views/controls/menu/submenu_view.h" +#include "views/controls/menu/native_menu_host_delegate.h" namespace views { //////////////////////////////////////////////////////////////////////////////// // MenuHostWin, public: -MenuHostWin::MenuHostWin(SubmenuView* submenu) - : destroying_(false), - submenu_(submenu), - owns_capture_(false) { - CreateParams params; - params.type = CreateParams::TYPE_MENU; - params.has_dropshadow = true; - SetCreateParams(params); +MenuHostWin::MenuHostWin(internal::NativeMenuHostDelegate* delegate) + : delegate_(delegate) { } MenuHostWin::~MenuHostWin() { @@ -31,100 +21,49 @@ MenuHostWin::~MenuHostWin() { //////////////////////////////////////////////////////////////////////////////// // MenuHostWin, NativeMenuHost implementation: -void MenuHostWin::InitMenuHost(HWND parent, - const gfx::Rect& bounds, - View* contents_view, - bool do_capture) { +void MenuHostWin::InitMenuHost(gfx::NativeWindow parent, + const gfx::Rect& bounds) { WidgetWin::Init(parent, bounds); - SetContentsView(contents_view); - ShowMenuHost(do_capture); } -bool MenuHostWin::IsMenuHostVisible() { - return IsVisible(); -} - -void MenuHostWin::ShowMenuHost(bool do_capture) { - // We don't want to take focus away from the hosting window. - ShowWindow(SW_SHOWNA); - - if (do_capture) - DoCapture(); -} - -void MenuHostWin::HideMenuHost() { - // Make sure we release capture before hiding. - ReleaseMenuHostCapture(); - - WidgetWin::Hide(); -} - -void MenuHostWin::DestroyMenuHost() { - HideMenuHost(); - destroying_ = true; - CloseNow(); -} - -void MenuHostWin::SetMenuHostBounds(const gfx::Rect& bounds) { - SetBounds(bounds); -} - -void MenuHostWin::ReleaseMenuHostCapture() { - if (owns_capture_) { - owns_capture_ = false; - ::ReleaseCapture(); - } +void MenuHostWin::StartCapturing() { + SetMouseCapture(); } -gfx::NativeWindow MenuHostWin::GetMenuHostWindow() { - return GetNativeView(); +NativeWidget* MenuHostWin::AsNativeWidget() { + return this; } //////////////////////////////////////////////////////////////////////////////// // MenuHostWin, WidgetWin overrides: void MenuHostWin::OnDestroy() { - if (!destroying_) { - // We weren't explicitly told to destroy ourselves, which means the menu was - // deleted out from under us (the window we're parented to was closed). Tell - // the SubmenuView to drop references to us. - submenu_->MenuHostDestroyed(); - } + delegate_->OnNativeMenuHostDestroy(); WidgetWin::OnDestroy(); } -void MenuHostWin::OnCaptureChanged(HWND hwnd) { - WidgetWin::OnCaptureChanged(hwnd); - owns_capture_ = false; -} - void MenuHostWin::OnCancelMode() { - submenu_->GetMenuItem()->GetMenuController()->Cancel( - MenuController::EXIT_ALL); + delegate_->OnNativeMenuHostCancelCapture(); + WidgetWin::OnCancelMode(); } +// TODO(beng): remove once MenuHost is-a Widget RootView* MenuHostWin::CreateRootView() { - return new MenuHostRootView(this, submenu_); + return delegate_->CreateRootView(); } +// TODO(beng): remove once MenuHost is-a Widget bool MenuHostWin::ShouldReleaseCaptureOnMouseReleased() const { - return false; -} - -//////////////////////////////////////////////////////////////////////////////// -// MenuHostWin, private: - -void MenuHostWin::DoCapture() { - owns_capture_ = true; - SetMouseCapture(); + return delegate_->ShouldReleaseCaptureOnMouseRelease(); } //////////////////////////////////////////////////////////////////////////////// // NativeMenuHost, public: // static -NativeMenuHost* NativeMenuHost::CreateNativeMenuHost(SubmenuView* submenu) { - return new MenuHostWin(submenu); +NativeMenuHost* NativeMenuHost::CreateNativeMenuHost( + internal::NativeMenuHostDelegate* delegate) { + return new MenuHostWin(delegate); } } // namespace views diff --git a/views/controls/menu/menu_host_win.h b/views/controls/menu/menu_host_win.h index f605275..1558a6e 100644 --- a/views/controls/menu/menu_host_win.h +++ b/views/controls/menu/menu_host_win.h @@ -10,47 +10,31 @@ #include "views/widget/widget_win.h" namespace views { - -class SubmenuView; +namespace internal { +class NativeMenuHostDelegate; +} // MenuHost implementation for windows. class MenuHostWin : public WidgetWin, public NativeMenuHost { public: - explicit MenuHostWin(SubmenuView* submenu); + explicit MenuHostWin(internal::NativeMenuHostDelegate* delegate); virtual ~MenuHostWin(); private: // Overridden from NativeMenuHost: virtual void InitMenuHost(gfx::NativeWindow parent, - const gfx::Rect& bounds, - View* contents_view, - bool do_capture) OVERRIDE; - virtual bool IsMenuHostVisible() OVERRIDE; - virtual void ShowMenuHost(bool do_capture) OVERRIDE; - virtual void HideMenuHost() OVERRIDE; - virtual void DestroyMenuHost() OVERRIDE; - virtual void SetMenuHostBounds(const gfx::Rect& bounds) OVERRIDE; - virtual void ReleaseMenuHostCapture() OVERRIDE; - virtual gfx::NativeWindow GetMenuHostWindow() OVERRIDE; + const gfx::Rect& bounds) OVERRIDE; + virtual void StartCapturing() OVERRIDE; + virtual NativeWidget* AsNativeWidget() OVERRIDE; // Overridden from WidgetWin: virtual void OnDestroy() OVERRIDE; - virtual void OnCaptureChanged(HWND hwnd) OVERRIDE; virtual void OnCancelMode() OVERRIDE; virtual RootView* CreateRootView() OVERRIDE; virtual bool ShouldReleaseCaptureOnMouseReleased() const OVERRIDE; - void DoCapture(); - - // If true, DestroyMenuHost has been invoked. - bool destroying_; - - // If true, we own the capture and need to release it. - bool owns_capture_; - - // The view we contain. - SubmenuView* submenu_; + scoped_ptr<internal::NativeMenuHostDelegate> delegate_; DISALLOW_COPY_AND_ASSIGN(MenuHostWin); }; diff --git a/views/controls/menu/native_menu_host.h b/views/controls/menu/native_menu_host.h index da8de47..0b64ca9 100644 --- a/views/controls/menu/native_menu_host.h +++ b/views/controls/menu/native_menu_host.h @@ -12,43 +12,26 @@ class Rect; } namespace views { - -class SubmenuView; -class View; +class NativeWidget; +namespace internal { +class NativeMenuHostDelegate; +} class NativeMenuHost { public: virtual ~NativeMenuHost() {} - static NativeMenuHost* CreateNativeMenuHost(SubmenuView* submenu); + static NativeMenuHost* CreateNativeMenuHost( + internal::NativeMenuHostDelegate* delegate); // Initializes and shows the MenuHost. virtual void InitMenuHost(gfx::NativeWindow parent, - const gfx::Rect& bounds, - View* contents_view, - bool do_capture) = 0; - - // Returns true if the menu host is visible. - virtual bool IsMenuHostVisible() = 0; - - // Shows the menu host. If |do_capture| is true the menu host should do a - // mouse grab. - virtual void ShowMenuHost(bool do_capture) = 0; - - // Hides the menu host. - virtual void HideMenuHost() = 0; - - // Destroys and deletes the menu host. - virtual void DestroyMenuHost() = 0; - - // Sets the bounds of the menu host. - virtual void SetMenuHostBounds(const gfx::Rect& bounds) = 0; + const gfx::Rect& bounds) = 0; - // Releases a mouse grab installed by |ShowMenuHost|. - virtual void ReleaseMenuHostCapture() = 0; + // Starts capturing input events. + virtual void StartCapturing() = 0; - // Returns the native window of the MenuHost. - virtual gfx::NativeWindow GetMenuHostWindow() = 0; + virtual NativeWidget* AsNativeWidget() = 0; }; } // namespace views diff --git a/views/controls/menu/native_menu_host_delegate.h b/views/controls/menu/native_menu_host_delegate.h index 28598c6..e6d3de8 100644 --- a/views/controls/menu/native_menu_host_delegate.h +++ b/views/controls/menu/native_menu_host_delegate.h @@ -6,11 +6,24 @@ #define VIEWS_CONTROLS_MENU_NATIVE_MENU_HOST_DELEGATE_H_ namespace views { +class MenuHost; +class RootView; namespace internal { class NativeMenuHostDelegate { public: virtual ~NativeMenuHostDelegate() {} + + // Called when the NativeMenuHost is being destroyed. + virtual void OnNativeMenuHostDestroy() = 0; + + // Called when the NativeMenuHost is losing input capture. + virtual void OnNativeMenuHostCancelCapture() = 0; + + // Pass-thrus for Widget overrides. + // TODO(beng): Remove once MenuHost is-a Widget. + virtual RootView* CreateRootView() = 0; + virtual bool ShouldReleaseCaptureOnMouseRelease() const = 0; }; } // namespace internal diff --git a/views/controls/menu/submenu_view.cc b/views/controls/menu/submenu_view.cc index 3192529..117496d 100644 --- a/views/controls/menu/submenu_view.cc +++ b/views/controls/menu/submenu_view.cc @@ -321,10 +321,6 @@ MenuScrollViewContainer* SubmenuView::GetScrollViewContainer() { return scroll_view_container_; } -gfx::NativeWindow SubmenuView::native_window() const { - return host_ ? host_->GetMenuHostWindow() : NULL; -} - void SubmenuView::MenuHostDestroyed() { host_ = NULL; GetMenuItem()->GetMenuController()->Cancel(MenuController::EXIT_DESTROYED); diff --git a/views/controls/menu/submenu_view.h b/views/controls/menu/submenu_view.h index 8eb41f2..50f9a6b 100644 --- a/views/controls/menu/submenu_view.h +++ b/views/controls/menu/submenu_view.h @@ -121,9 +121,6 @@ class SubmenuView : public View { // Returns the container for the SubmenuView. MenuScrollViewContainer* GetScrollViewContainer(); - // Returns the NativeWindow host of the menu, or NULL if not showing. - gfx::NativeWindow native_window() const; - // Invoked if the menu is prematurely destroyed. This can happen if the window // closes while the menu is shown. If invoked the SubmenuView must drop all // references to the MenuHost as the MenuHost is about to be deleted. diff --git a/views/widget/native_widget.h b/views/widget/native_widget.h index d9a1184..c46aff3 100644 --- a/views/widget/native_widget.h +++ b/views/widget/native_widget.h @@ -9,6 +9,7 @@ #include <set> #include "ui/gfx/native_widget_types.h" +#include "views/widget/widget.h" namespace gfx { class Rect; @@ -22,7 +23,6 @@ namespace views { class InputMethod; class TooltipManager; -class Widget; //////////////////////////////////////////////////////////////////////////////// // NativeWidget interface @@ -58,6 +58,9 @@ class NativeWidget { static void ReparentNativeView(gfx::NativeView native_view, gfx::NativeView new_parent); + // Sets the create params for the NativeWidget. + virtual void SetCreateParams(const Widget::CreateParams& params) = 0; + // Returns the Widget associated with this NativeWidget. This function is // guaranteed to return non-NULL for the lifetime of the NativeWidget. virtual Widget* GetWidget() = 0; diff --git a/views/widget/widget.cc b/views/widget/widget.cc index 320f69f..e707a2b 100644 --- a/views/widget/widget.cc +++ b/views/widget/widget.cc @@ -58,6 +58,10 @@ Widget::Widget() Widget::~Widget() { } +void Widget::SetCreateParams(const CreateParams& params) { + native_widget_->SetCreateParams(params); +} + // Unconverted methods (see header) -------------------------------------------- void Widget::Init(gfx::NativeView parent, const gfx::Rect& bounds) { diff --git a/views/widget/widget.h b/views/widget/widget.h index 8bf3ec0..e4c1035 100644 --- a/views/widget/widget.h +++ b/views/widget/widget.h @@ -104,6 +104,9 @@ class Widget : public internal::NativeWidgetDelegate, const Widget* target, gfx::Rect* rect); + // Sets the creation params for the Widget. + void SetCreateParams(const CreateParams& params); + // Unconverted methods ------------------------------------------------------- // TODO(beng): diff --git a/views/widget/widget_gtk.cc b/views/widget/widget_gtk.cc index 00824f5..da998b4 100644 --- a/views/widget/widget_gtk.cc +++ b/views/widget/widget_gtk.cc @@ -304,26 +304,6 @@ WidgetGtk::~WidgetGtk() { ActiveWindowWatcherX::RemoveObserver(this); } -void WidgetGtk::SetCreateParams(const CreateParams& params) { - // Set non-style attributes. - set_delete_on_destroy(params.delete_on_destroy); - - if (params.transparent) - MakeTransparent(); - if (!params.accept_events) - MakeIgnoreEvents(); - - if (params.type == CreateParams::TYPE_MENU) { - GdkEvent* event = gtk_get_current_event(); - if (event) { - is_mouse_button_pressed_ = event->type == GDK_BUTTON_PRESS || - event->type == GDK_2BUTTON_PRESS || - event->type == GDK_3BUTTON_PRESS; - gdk_event_free(event); - } - } -} - GtkWindow* WidgetGtk::GetTransientParent() const { return (type_ != TYPE_CHILD && widget_) ? gtk_window_get_transient_for(GTK_WINDOW(widget_)) : NULL; @@ -749,6 +729,28 @@ void WidgetGtk::UpdateFreezeUpdatesProperty(GtkWindow* window, bool enable) { //////////////////////////////////////////////////////////////////////////////// // WidgetGtk, NativeWidget implementation: +void WidgetGtk::SetCreateParams(const CreateParams& params) { + DCHECK(!GetNativeView()); + + // Set non-style attributes. + set_delete_on_destroy(params.delete_on_destroy); + + if (params.transparent) + MakeTransparent(); + if (!params.accept_events) + MakeIgnoreEvents(); + + if (params.type == CreateParams::TYPE_MENU) { + GdkEvent* event = gtk_get_current_event(); + if (event) { + is_mouse_button_pressed_ = event->type == GDK_BUTTON_PRESS || + event->type == GDK_2BUTTON_PRESS || + event->type == GDK_3BUTTON_PRESS; + gdk_event_free(event); + } + } +} + Widget* WidgetGtk::GetWidget() { return this; } diff --git a/views/widget/widget_gtk.h b/views/widget/widget_gtk.h index 323f886..4028997 100644 --- a/views/widget/widget_gtk.h +++ b/views/widget/widget_gtk.h @@ -67,9 +67,6 @@ class WidgetGtk : public Widget, explicit WidgetGtk(Type type); virtual ~WidgetGtk(); - // Initializes native widget properties based on |params|. - void SetCreateParams(const CreateParams& params); - // Marks this window as transient to its parent. A window that is transient // to its parent results in the parent rendering active when the child is // active. @@ -191,6 +188,7 @@ class WidgetGtk : public Widget, static void UpdateFreezeUpdatesProperty(GtkWindow* window, bool enable); // Overridden from NativeWidget: + virtual void SetCreateParams(const CreateParams& params) OVERRIDE; virtual Widget* GetWidget() OVERRIDE; virtual void SetNativeWindowProperty(const char* name, void* value) OVERRIDE; virtual void* GetNativeWindowProperty(const char* name) OVERRIDE; diff --git a/views/widget/widget_win.cc b/views/widget/widget_win.cc index 1cadfb1..3c526b6 100644 --- a/views/widget/widget_win.cc +++ b/views/widget/widget_win.cc @@ -157,59 +157,6 @@ WidgetWin::~WidgetWin() { DestroyRootView(); } -void WidgetWin::SetCreateParams(const CreateParams& params) { - // Set non-style attributes. - set_delete_on_destroy(params.delete_on_destroy); - - DWORD style = WS_CLIPCHILDREN | WS_CLIPSIBLINGS; - DWORD ex_style = 0; - DWORD class_style = CS_DBLCLKS; - - // Set type-independent style attributes. - if (params.child) - style |= WS_CHILD | WS_VISIBLE; - if (!params.accept_events) - ex_style |= WS_EX_TRANSPARENT; - if (!params.can_activate) - ex_style |= WS_EX_NOACTIVATE; - if (params.keep_on_top) - ex_style |= WS_EX_TOPMOST; - if (params.mirror_origin_in_rtl) - ex_style |= l10n_util::GetExtendedTooltipStyles(); - if (params.transparent) - ex_style |= WS_EX_LAYERED; - if (params.has_dropshadow) { - class_style |= (base::win::GetVersion() < base::win::VERSION_XP) ? - 0 : CS_DROPSHADOW; - } - - // Set type-dependent style attributes. - switch (params.type) { - case CreateParams::TYPE_WINDOW: - case CreateParams::TYPE_CONTROL: - break; - case CreateParams::TYPE_POPUP: - style |= WS_POPUP; - ex_style |= WS_EX_TOOLWINDOW; - break; - case CreateParams::TYPE_MENU: - style |= WS_POPUP; - is_mouse_button_pressed_ = - ((GetKeyState(VK_LBUTTON) & 0x80) || - (GetKeyState(VK_RBUTTON) & 0x80) || - (GetKeyState(VK_MBUTTON) & 0x80) || - (GetKeyState(VK_XBUTTON1) & 0x80) || - (GetKeyState(VK_XBUTTON2) & 0x80)); - break; - default: - NOTREACHED(); - } - - set_initial_class_style(class_style); - set_window_style(style); - set_window_ex_style(ex_style); -} - // static WidgetWin* WidgetWin::GetWidget(HWND hwnd) { // TODO(jcivelli): http://crbug.com/44499 We need a way to test that hwnd is @@ -297,6 +244,61 @@ void WidgetWin::ViewHierarchyChanged(bool is_add, View* parent, //////////////////////////////////////////////////////////////////////////////// // WidgetWin, NativeWidget implementation: +void WidgetWin::SetCreateParams(const CreateParams& params) { + DCHECK(!GetNativeView()); + + // Set non-style attributes. + set_delete_on_destroy(params.delete_on_destroy); + + DWORD style = WS_CLIPCHILDREN | WS_CLIPSIBLINGS; + DWORD ex_style = 0; + DWORD class_style = CS_DBLCLKS; + + // Set type-independent style attributes. + if (params.child) + style |= WS_CHILD | WS_VISIBLE; + if (!params.accept_events) + ex_style |= WS_EX_TRANSPARENT; + if (!params.can_activate) + ex_style |= WS_EX_NOACTIVATE; + if (params.keep_on_top) + ex_style |= WS_EX_TOPMOST; + if (params.mirror_origin_in_rtl) + ex_style |= l10n_util::GetExtendedTooltipStyles(); + if (params.transparent) + ex_style |= WS_EX_LAYERED; + if (params.has_dropshadow) { + class_style |= (base::win::GetVersion() < base::win::VERSION_XP) ? + 0 : CS_DROPSHADOW; + } + + // Set type-dependent style attributes. + switch (params.type) { + case CreateParams::TYPE_WINDOW: + case CreateParams::TYPE_CONTROL: + break; + case CreateParams::TYPE_POPUP: + style |= WS_POPUP; + ex_style |= WS_EX_TOOLWINDOW; + break; + case CreateParams::TYPE_MENU: + style |= WS_POPUP; + is_mouse_button_pressed_ = + ((GetKeyState(VK_LBUTTON) & 0x80) || + (GetKeyState(VK_RBUTTON) & 0x80) || + (GetKeyState(VK_MBUTTON) & 0x80) || + (GetKeyState(VK_XBUTTON1) & 0x80) || + (GetKeyState(VK_XBUTTON2) & 0x80)); + break; + default: + NOTREACHED(); + } + + set_initial_class_style(class_style); + set_window_style(style); + set_window_ex_style(ex_style); +} + Widget* WidgetWin::GetWidget() { return this; } diff --git a/views/widget/widget_win.h b/views/widget/widget_win.h index 6c72a22..c7b83e8 100644 --- a/views/widget/widget_win.h +++ b/views/widget/widget_win.h @@ -88,9 +88,6 @@ class WidgetWin : public ui::WindowImpl, WidgetWin(); virtual ~WidgetWin(); - // Initializes native widget properties based on |params|. - void SetCreateParams(const CreateParams& params); - // Returns the Widget associated with the specified HWND (if any). static WidgetWin* GetWidget(HWND hwnd); @@ -203,6 +200,7 @@ class WidgetWin : public ui::WindowImpl, } // Overridden from NativeWidget: + virtual void SetCreateParams(const Widget::CreateParams& params) OVERRIDE; virtual Widget* GetWidget() OVERRIDE; virtual void SetNativeWindowProperty(const char* name, void* value) OVERRIDE; virtual void* GetNativeWindowProperty(const char* name) OVERRIDE; |