diff options
author | ben@chromium.org <ben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-03-16 18:12:09 +0000 |
---|---|---|
committer | ben@chromium.org <ben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-03-16 18:12:09 +0000 |
commit | 63b8201d4abcbfcc9d27ce3b410e6206e19d64c5 (patch) | |
tree | c35d6a8f0f9afcd66dfa31f3db8d0643074ac8ea /views | |
parent | 063002ca22759a0f70108956dd5f4c0a74d8fcda (diff) | |
download | chromium_src-63b8201d4abcbfcc9d27ce3b410e6206e19d64c5.zip chromium_src-63b8201d4abcbfcc9d27ce3b410e6206e19d64c5.tar.gz chromium_src-63b8201d4abcbfcc9d27ce3b410e6206e19d64c5.tar.bz2 |
Re-lands:
Add native capture API to Widget, and fix a bug in Window where we wouldn't let the window be closed from the X.
BUG=72040
TEST=none
R=sky
Review URL: http://codereview.chromium.org/6670049
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@78394 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'views')
-rw-r--r-- | views/controls/menu/menu_host_gtk.cc | 8 | ||||
-rw-r--r-- | views/controls/menu/menu_host_gtk.h | 28 | ||||
-rw-r--r-- | views/controls/menu/menu_host_win.cc | 3 | ||||
-rw-r--r-- | views/widget/native_widget.h | 7 | ||||
-rw-r--r-- | views/widget/widget_gtk.cc | 52 | ||||
-rw-r--r-- | views/widget/widget_gtk.h | 15 | ||||
-rw-r--r-- | views/widget/widget_win.cc | 41 | ||||
-rw-r--r-- | views/widget/widget_win.h | 11 | ||||
-rw-r--r-- | views/window/window_win.cc | 2 |
9 files changed, 82 insertions, 85 deletions
diff --git a/views/controls/menu/menu_host_gtk.cc b/views/controls/menu/menu_host_gtk.cc index c41da16..cc2faeb 100644 --- a/views/controls/menu/menu_host_gtk.cc +++ b/views/controls/menu/menu_host_gtk.cc @@ -92,7 +92,7 @@ void MenuHostGtk::SetMenuHostBounds(const gfx::Rect& bounds) { } void MenuHostGtk::ReleaseMenuHostCapture() { - ReleaseGrab(); + ReleaseNativeCapture(); } gfx::NativeWindow MenuHostGtk::GetMenuHostWindow() { @@ -107,8 +107,8 @@ bool MenuHostGtk::ReleaseCaptureOnMouseReleased() { return false; } -void MenuHostGtk::ReleaseGrab() { - WidgetGtk::ReleaseGrab(); +void MenuHostGtk::ReleaseNativeCapture() { + WidgetGtk::ReleaseNativeCapture(); if (did_input_grab_) { did_input_grab_ = false; gdk_pointer_ungrab(GDK_CURRENT_TIME); @@ -150,7 +150,7 @@ void MenuHostGtk::DoCapture() { gtk_grab_remove(current_grab_window); // Make sure all app mouse/keyboard events are targetted at us only. - DoGrab(); + SetNativeCapture(); // 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 diff --git a/views/controls/menu/menu_host_gtk.h b/views/controls/menu/menu_host_gtk.h index 36a3737..626433c 100644 --- a/views/controls/menu/menu_host_gtk.h +++ b/views/controls/menu/menu_host_gtk.h @@ -24,27 +24,27 @@ class MenuHostGtk : public WidgetGtk, public MenuHost { virtual void InitMenuHost(gfx::NativeWindow parent, const gfx::Rect& bounds, View* contents_view, - bool do_capture); - virtual bool IsMenuHostVisible(); - virtual void ShowMenuHost(bool do_capture); - virtual void HideMenuHost(); - virtual void DestroyMenuHost(); - virtual void SetMenuHostBounds(const gfx::Rect& bounds); - virtual void ReleaseMenuHostCapture(); - virtual gfx::NativeWindow GetMenuHostWindow(); + 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; protected: virtual RootView* CreateRootView(); - // Overriden to return false, we do NOT want to release capture on mouse + // Overridden to return false, we do NOT want to release capture on mouse // release. - virtual bool ReleaseCaptureOnMouseReleased(); + virtual bool ReleaseCaptureOnMouseReleased() OVERRIDE; - // Overriden to also release input grab. - virtual void ReleaseGrab(); + // Overridden to also release input grab. + virtual void ReleaseNativeCapture() OVERRIDE; - virtual void OnDestroy(GtkWidget* object); - virtual void HandleGrabBroke(); + virtual void OnDestroy(GtkWidget* object) OVERRIDE; + virtual void HandleGrabBroke() OVERRIDE; private: void DoCapture(); diff --git a/views/controls/menu/menu_host_win.cc b/views/controls/menu/menu_host_win.cc index 0758f4b..1beda38 100644 --- a/views/controls/menu/menu_host_win.cc +++ b/views/controls/menu/menu_host_win.cc @@ -117,8 +117,7 @@ bool MenuHostWin::ReleaseCaptureOnMouseReleased() { void MenuHostWin::DoCapture() { owns_capture_ = true; - SetCapture(); - has_capture_ = true; + SetNativeCapture(); } } // namespace views diff --git a/views/widget/native_widget.h b/views/widget/native_widget.h index a833664..9d6051f 100644 --- a/views/widget/native_widget.h +++ b/views/widget/native_widget.h @@ -69,6 +69,13 @@ class NativeWidget { // Returns true if a system screen reader is active for the NativeWidget. virtual bool IsScreenReaderActive() const = 0; + // Sets or releases event capturing for this native widget. + virtual void SetNativeCapture() = 0; + virtual void ReleaseNativeCapture() = 0; + + // Returns true if this native widget is capturing all events. + virtual bool HasNativeCapture() const = 0; + protected: friend class Widget; diff --git a/views/widget/widget_gtk.cc b/views/widget/widget_gtk.cc index e96df66..bd37038 100644 --- a/views/widget/widget_gtk.cc +++ b/views/widget/widget_gtk.cc @@ -265,7 +265,6 @@ WidgetGtk::WidgetGtk(Type type) widget_(NULL), window_contents_(NULL), is_mouse_down_(false), - has_capture_(false), last_mouse_event_was_move_(false), ALLOW_THIS_IN_INITIALIZER_LIST(close_widget_factory_(this)), delete_on_destroy_(true), @@ -725,6 +724,22 @@ bool WidgetGtk::IsScreenReaderActive() const { return false; } +void WidgetGtk::SetNativeCapture() { + DCHECK(!HasNativeCapture()); + gtk_grab_add(window_contents_); +} + +void WidgetGtk::ReleaseNativeCapture() { + if (HasNativeCapture()) + gtk_grab_remove(window_contents_); +} + +bool WidgetGtk::HasNativeCapture() const { + // TODO(beng): Should be able to use gtk_widget_has_grab() here but the + // trybots don't have Gtk 2.18. + return GTK_WIDGET_HAS_GRAB(window_contents_); +} + gfx::Rect WidgetGtk::GetWindowScreenBounds() const { // Client == Window bounds on Gtk. return GetClientAreaScreenBounds(); @@ -1041,7 +1056,7 @@ gboolean WidgetGtk::OnEnterNotify(GtkWidget* widget, GdkEventCrossing* event) { return false; } - if (has_capture_ && event->mode == GDK_CROSSING_GRAB) { + if (HasNativeCapture() && event->mode == GDK_CROSSING_GRAB) { // Doing a grab results an async enter event, regardless of where the mouse // is. We don't want to generate a mouse move in this case. return false; @@ -1074,7 +1089,7 @@ gboolean WidgetGtk::OnEnterNotify(GtkWidget* widget, GdkEventCrossing* event) { gboolean WidgetGtk::OnLeaveNotify(GtkWidget* widget, GdkEventCrossing* event) { last_mouse_event_was_move_ = false; - if (!has_capture_ && !is_mouse_down_) { + if (!HasNativeCapture() && !is_mouse_down_) { MouseEvent mouse_event(reinterpret_cast<GdkEvent*>(event)); GetRootView()->OnMouseExited(mouse_event); } @@ -1085,7 +1100,7 @@ gboolean WidgetGtk::OnMotionNotify(GtkWidget* widget, GdkEventMotion* event) { int x = 0, y = 0; GetContainedWidgetEventCoordinates(event, &x, &y); - if (has_capture_ && is_mouse_down_) { + if (HasNativeCapture() && is_mouse_down_) { last_mouse_event_was_move_ = false; int flags = Event::GetFlagsFromGdkState(event->state); MouseEvent mouse_drag(ui::ET_MOUSE_DRAGGED, x, y, flags); @@ -1242,25 +1257,10 @@ bool WidgetGtk::ReleaseCaptureOnMouseReleased() { return true; } -void WidgetGtk::DoGrab() { - has_capture_ = true; - gtk_grab_add(window_contents_); -} - -void WidgetGtk::ReleaseGrab() { - if (has_capture_) { - has_capture_ = false; - gtk_grab_remove(window_contents_); - } -} - void WidgetGtk::HandleGrabBroke() { - if (has_capture_) { - if (is_mouse_down_) - GetRootView()->ProcessMouseDragCanceled(); - is_mouse_down_ = false; - has_capture_ = false; - } + if (is_mouse_down_) + GetRootView()->ProcessMouseDragCanceled(); + is_mouse_down_ = false; } //////////////////////////////////////////////////////////////////////////////// @@ -1307,8 +1307,8 @@ bool WidgetGtk::ProcessMousePressed(GdkEventButton* event) { if (GetRootView()->OnMousePressed(mouse_pressed)) { is_mouse_down_ = true; - if (!has_capture_) - DoGrab(); + if (!HasNativeCapture()) + SetNativeCapture(); return true; } @@ -1325,8 +1325,8 @@ void WidgetGtk::ProcessMouseReleased(GdkEventButton* event) { GetFlagsForEventButton(*event)); // Release the capture first, that way we don't get confused if // OnMouseReleased blocks. - if (has_capture_ && ReleaseCaptureOnMouseReleased()) - ReleaseGrab(); + if (HasNativeCapture() && ReleaseCaptureOnMouseReleased()) + ReleaseNativeCapture(); is_mouse_down_ = false; // GTK generates a mouse release at the end of dnd. We need to ignore it. if (!drag_data_) diff --git a/views/widget/widget_gtk.h b/views/widget/widget_gtk.h index 370e9cf..584be82 100644 --- a/views/widget/widget_gtk.h +++ b/views/widget/widget_gtk.h @@ -182,6 +182,9 @@ class WidgetGtk : public Widget, virtual void* GetNativeWindowProperty(const char* name) OVERRIDE; virtual TooltipManager* GetTooltipManager() const OVERRIDE; virtual bool IsScreenReaderActive() const OVERRIDE; + virtual void SetNativeCapture() OVERRIDE; + virtual void ReleaseNativeCapture() OVERRIDE; + virtual bool HasNativeCapture() const OVERRIDE; virtual gfx::Rect GetWindowScreenBounds() const OVERRIDE; virtual gfx::Rect GetClientAreaScreenBounds() const OVERRIDE; virtual void SetBounds(const gfx::Rect& bounds) OVERRIDE; @@ -263,19 +266,10 @@ class WidgetGtk : public Widget, void set_mouse_down(bool mouse_down) { is_mouse_down_ = mouse_down; } - // Do we own the mouse grab? - bool has_capture() const { return has_capture_; } - // Returns whether capture should be released on mouse release. The default // is true. virtual bool ReleaseCaptureOnMouseReleased(); - // Does a mouse grab on this widget. - virtual void DoGrab(); - - // Releases a grab done by this widget. - virtual void ReleaseGrab(); - // Invoked when input grab is stolen by other GtkWidget in the same // application. virtual void HandleGrabBroke(); @@ -347,9 +341,6 @@ class WidgetGtk : public Widget, // If true, the mouse is currently down. bool is_mouse_down_; - // Have we done a mouse grab? - bool has_capture_; - // The following are used to detect duplicate mouse move events and not // deliver them. Displaying a window may result in the system generating // duplicate move events even though the mouse hasn't moved. diff --git a/views/widget/widget_win.cc b/views/widget/widget_win.cc index 34a3ceb..d39f767 100644 --- a/views/widget/widget_win.cc +++ b/views/widget/widget_win.cc @@ -134,7 +134,6 @@ WidgetWin::WidgetWin() : ALLOW_THIS_IN_INITIALIZER_LIST(delegate_(this)), close_widget_factory_(this), active_mouse_tracking_flags_(0), - has_capture_(false), use_layered_buffer_(false), layered_alpha_(255), delete_on_destroy_(true), @@ -269,6 +268,19 @@ bool WidgetWin::IsScreenReaderActive() const { return screen_reader_active_; } +void WidgetWin::SetNativeCapture() { + DCHECK(!HasNativeCapture()); + SetCapture(hwnd()); +} + +void WidgetWin::ReleaseNativeCapture() { + ReleaseCapture(); +} + +bool WidgetWin::HasNativeCapture() const { + return GetCapture() == hwnd(); +} + gfx::Rect WidgetWin::GetWindowScreenBounds() const { RECT r; GetWindowRect(&r); @@ -489,12 +501,9 @@ void WidgetWin::OnCancelMode() { } void WidgetWin::OnCaptureChanged(HWND hwnd) { - if (has_capture_) { - if (is_mouse_down_) - GetRootView()->ProcessMouseDragCanceled(); - is_mouse_down_ = false; - has_capture_ = false; - } + if (is_mouse_down_) + GetRootView()->ProcessMouseDragCanceled(); + is_mouse_down_ = false; } void WidgetWin::OnClose() { @@ -927,10 +936,8 @@ bool WidgetWin::ProcessMousePressed(UINT message, GET_Y_LPARAM(l_param)); if (GetRootView()->OnMousePressed(MouseEvent(msg))) { is_mouse_down_ = true; - if (!has_capture_) { - SetCapture(); - has_capture_ = true; - } + if (!HasNativeCapture()) + SetNativeCapture(); return true; } return false; @@ -940,14 +947,12 @@ bool WidgetWin::ProcessMouseReleased(UINT message, WPARAM w_param, LPARAM l_param) { last_mouse_event_was_move_ = false; + is_mouse_down_ = false; // Release the capture first, that way we don't get confused if // OnMouseReleased blocks. - if (has_capture_ && ReleaseCaptureOnMouseReleased()) { - has_capture_ = false; - ReleaseCapture(); - } - is_mouse_down_ = false; + if (HasNativeCapture() && ReleaseCaptureOnMouseReleased()) + ReleaseNativeCapture(); MSG msg; MakeMSG(&msg, message, w_param, l_param, 0, GET_X_LPARAM(l_param), @@ -962,13 +967,13 @@ bool WidgetWin::ProcessMouseMoved(UINT message, // Windows only fires WM_MOUSELEAVE events if the application begins // "tracking" mouse events for a given HWND during WM_MOUSEMOVE events. // We need to call |TrackMouseEvents| to listen for WM_MOUSELEAVE. - if (!has_capture_) + if (!HasNativeCapture()) TrackMouseEvents((message == WM_NCMOUSEMOVE) ? TME_NONCLIENT | TME_LEAVE : TME_LEAVE); MSG msg; MakeMSG(&msg, message, w_param, l_param, 0, GET_X_LPARAM(l_param), GET_Y_LPARAM(l_param)); - if (has_capture_ && is_mouse_down_) + if (HasNativeCapture() && is_mouse_down_) GetRootView()->OnMouseDragged(MouseEvent(msg)); else if (!last_mouse_event_was_move_ || (last_mouse_move_x_ != GET_X_LPARAM(l_param) || diff --git a/views/widget/widget_win.h b/views/widget/widget_win.h index 9779bd8..47863c7 100644 --- a/views/widget/widget_win.h +++ b/views/widget/widget_win.h @@ -142,11 +142,6 @@ class WidgetWin : public ui::WindowImpl, return ::ShowWindow(GetNativeView(), command); } - HWND SetCapture() { - DCHECK(::IsWindow(GetNativeView())); - return ::SetCapture(GetNativeView()); - } - HWND GetParent() const { return ::GetParent(GetNativeView()); } @@ -208,6 +203,9 @@ class WidgetWin : public ui::WindowImpl, virtual void* GetNativeWindowProperty(const char* name) OVERRIDE; virtual TooltipManager* GetTooltipManager() const OVERRIDE; virtual bool IsScreenReaderActive() const OVERRIDE; + virtual void SetNativeCapture() OVERRIDE; + virtual void ReleaseNativeCapture() OVERRIDE; + virtual bool HasNativeCapture() const OVERRIDE; virtual gfx::Rect GetWindowScreenBounds() const OVERRIDE; virtual gfx::Rect GetClientAreaScreenBounds() const OVERRIDE; virtual void SetBounds(const gfx::Rect& bounds) OVERRIDE; @@ -416,9 +414,6 @@ class WidgetWin : public ui::WindowImpl, scoped_refptr<DropTargetWin> drop_target_; - // Whether or not we have capture the mouse. - bool has_capture_; - // If true, the mouse is currently down. bool is_mouse_down_; diff --git a/views/window/window_win.cc b/views/window/window_win.cc index 4f204da..301b5099 100644 --- a/views/window/window_win.cc +++ b/views/window/window_win.cc @@ -673,7 +673,7 @@ LRESULT WindowWin::OnNCMouseRange(UINT message, // We SetCapture() to ensure we only show the menu when the button down and // up are both on the caption. Note: this causes the button up to be // WM_RBUTTONUP instead of WM_NCRBUTTONUP. - SetCapture(); + SetNativeCapture(); } WidgetWin::OnNCMouseRange(message, w_param, l_param); |