summaryrefslogtreecommitdiffstats
path: root/views/widget
diff options
context:
space:
mode:
authorben@chromium.org <ben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-03-16 18:12:09 +0000
committerben@chromium.org <ben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-03-16 18:12:09 +0000
commit63b8201d4abcbfcc9d27ce3b410e6206e19d64c5 (patch)
treec35d6a8f0f9afcd66dfa31f3db8d0643074ac8ea /views/widget
parent063002ca22759a0f70108956dd5f4c0a74d8fcda (diff)
downloadchromium_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/widget')
-rw-r--r--views/widget/native_widget.h7
-rw-r--r--views/widget/widget_gtk.cc52
-rw-r--r--views/widget/widget_gtk.h15
-rw-r--r--views/widget/widget_win.cc41
-rw-r--r--views/widget/widget_win.h11
5 files changed, 62 insertions, 64 deletions
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_;