summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsadrul@chromium.org <sadrul@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-04-27 17:55:42 +0000
committersadrul@chromium.org <sadrul@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-04-27 17:55:42 +0000
commite789ff3b6f13d50c2599050c1b4797593c06cdfc (patch)
tree93ac9ce631970052e03a0795ab673c54631a7407
parentaa8e852c7cf3239f98d1441054392228560b3a98 (diff)
downloadchromium_src-e789ff3b6f13d50c2599050c1b4797593c06cdfc.zip
chromium_src-e789ff3b6f13d50c2599050c1b4797593c06cdfc.tar.gz
chromium_src-e789ff3b6f13d50c2599050c1b4797593c06cdfc.tar.bz2
Prevent a panel from blowing up when touched.
An event on touchui does not usually have an associated GDK event, so trying to access that causes a crash. So use the views API to get to the native event instead. BUG=touch a balloon/panel on chromeos, chrome crashes. TEST=manually Review URL: http://codereview.chromium.org/6902073 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@83175 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/chromeos/frame/panel_controller.cc89
1 files changed, 73 insertions, 16 deletions
diff --git a/chrome/browser/chromeos/frame/panel_controller.cc b/chrome/browser/chromeos/frame/panel_controller.cc
index b7513cb..e256b02 100644
--- a/chrome/browser/chromeos/frame/panel_controller.cc
+++ b/chrome/browser/chromeos/frame/panel_controller.cc
@@ -4,6 +4,13 @@
#include "chrome/browser/chromeos/frame/panel_controller.h"
+#if defined(TOUCH_UI)
+#include <X11/Xlib.h>
+#if defined(HAVE_XINPUT2)
+#include <X11/extensions/XInput2.h>
+#endif
+#endif
+
#include <vector>
#include "base/logging.h"
@@ -31,6 +38,41 @@
#include "views/widget/widget.h"
#include "views/window/window.h"
+#if defined(TOUCH_UI)
+namespace {
+
+gfx::Point RootLocationFromXEvent(const XEvent* xev) {
+ switch (xev->type) {
+ case ButtonPress:
+ case ButtonRelease:
+ return gfx::Point(xev->xbutton.x_root, xev->xbutton.y_root);
+ case MotionNotify:
+ return gfx::Point(xev->xmotion.x_root, xev->xmotion.y_root);
+
+#if defined(HAVE_XINPUT2)
+ case GenericEvent: {
+ const XIDeviceEvent* xiev =
+ static_cast<XIDeviceEvent*>(xev->xcookie.data);
+ switch (xiev->evtype) {
+ case XI_ButtonPress:
+ case XI_ButtonRelease:
+ case XI_Motion:
+ return gfx::Point(static_cast<int>(xiev->root_x),
+ static_cast<int>(xiev->root_y));
+ }
+ }
+#endif // defined(HAVE_XINPUT2)
+
+ default:
+ NOTREACHED();
+ }
+
+ return gfx::Point();
+}
+
+} // namespace
+#endif // defined(TOUCH_UI)
+
namespace chromeos {
static int close_button_width;
@@ -202,9 +244,7 @@ void PanelController::SetUrgent(bool urgent) {
bool PanelController::TitleMousePressed(const views::MouseEvent& event) {
if (!event.IsOnlyLeftMouseButton())
return false;
- GdkEvent* gdk_event = gtk_get_current_event();
- if (gdk_event->type != GDK_BUTTON_PRESS) {
- gdk_event_free(gdk_event);
+ if (event.type() != ui::ET_MOUSE_PRESSED) {
NOTREACHED();
return false;
}
@@ -216,14 +256,22 @@ bool PanelController::TitleMousePressed(const views::MouseEvent& event) {
gint title_width = 1;
gtk_window_get_size(GTK_WINDOW(title_), &title_width, NULL);
- GdkEventButton last_button_event = gdk_event->button;
mouse_down_ = true;
- mouse_down_abs_x_ = last_button_event.x_root;
- mouse_down_abs_y_ = last_button_event.y_root;
mouse_down_offset_x_ = event.x() - title_width;
mouse_down_offset_y_ = event.y();
dragging_ = false;
- gdk_event_free(gdk_event);
+
+#if !defined(TOUCH_UI)
+ const GdkEvent* gdk_event = event.native_event();
+ GdkEventButton last_button_event = gdk_event->button;
+ mouse_down_abs_x_ = last_button_event.x_root;
+ mouse_down_abs_y_ = last_button_event.y_root;
+#else
+ const XEvent* xev = event.native_event_2();
+ gfx::Point abs_location = RootLocationFromXEvent(xev);
+ mouse_down_abs_x_ = abs_location.x();
+ mouse_down_abs_y_ = abs_location.y();
+#endif
return true;
}
@@ -265,28 +313,37 @@ void PanelController::SetState(State state) {
bool PanelController::TitleMouseDragged(const views::MouseEvent& event) {
if (!mouse_down_)
return false;
- GdkEvent* gdk_event = gtk_get_current_event();
- if (gdk_event->type != GDK_MOTION_NOTIFY) {
- gdk_event_free(gdk_event);
+ if (event.type() != ui::ET_MOUSE_MOVED &&
+ event.type() != ui::ET_MOUSE_DRAGGED) {
NOTREACHED();
return false;
}
+
+#if !defined(TOUCH_UI)
+ const GdkEvent* gdk_event = event.native_event();
GdkEventMotion last_motion_event = gdk_event->motion;
+ int x_root = last_motion_event.x_root;
+ int y_root = last_motion_event.y_root;
+#else
+ const XEvent* xev = event.native_event_2();
+ gfx::Point abs_location = RootLocationFromXEvent(xev);
+ int x_root = abs_location.x();
+ int y_root = abs_location.y();
+#endif
+
if (!dragging_) {
- if (views::View::ExceededDragThreshold(
- last_motion_event.x_root - mouse_down_abs_x_,
- last_motion_event.y_root - mouse_down_abs_y_)) {
+ if (views::View::ExceededDragThreshold(x_root - mouse_down_abs_x_,
+ y_root - mouse_down_abs_y_)) {
dragging_ = true;
}
}
if (dragging_) {
WmIpc::Message msg(WM_IPC_MESSAGE_WM_NOTIFY_PANEL_DRAGGED);
msg.set_param(0, panel_xid_);
- msg.set_param(1, last_motion_event.x_root - mouse_down_offset_x_);
- msg.set_param(2, last_motion_event.y_root - mouse_down_offset_y_);
+ msg.set_param(1, x_root - mouse_down_offset_x_);
+ msg.set_param(2, y_root - mouse_down_offset_y_);
WmIpc::instance()->SendMessage(msg);
}
- gdk_event_free(gdk_event);
return true;
}