summaryrefslogtreecommitdiffstats
path: root/views
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
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')
-rw-r--r--views/controls/menu/menu_host_gtk.cc8
-rw-r--r--views/controls/menu/menu_host_gtk.h28
-rw-r--r--views/controls/menu/menu_host_win.cc3
-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
-rw-r--r--views/window/window_win.cc2
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);