summaryrefslogtreecommitdiffstats
path: root/chrome/browser/automation/ui_controls_linux.cc
diff options
context:
space:
mode:
authorsky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-08-26 03:27:29 +0000
committersky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-08-26 03:27:29 +0000
commitc0cbacb7525dfb39b346f597d5c7947fa1f9f63b (patch)
tree95d16f97e42d0f5ffccc08b701e0e1b2fa1572dc /chrome/browser/automation/ui_controls_linux.cc
parent7bc5f1bb093daa602ac483051bd0071f8064779b (diff)
downloadchromium_src-c0cbacb7525dfb39b346f597d5c7947fa1f9f63b.zip
chromium_src-c0cbacb7525dfb39b346f597d5c7947fa1f9f63b.tar.gz
chromium_src-c0cbacb7525dfb39b346f597d5c7947fa1f9f63b.tar.bz2
Couple of tweaks to ui_controls_linux:
. Moves listening from DidProcess to WillProcess. This is necessitated by the bookmark bar (chrome menu) tests that spawn a nested run loop, which results in DidProcess not getting sent and the test wedging. This brings the code closer in line with Windows. . If there is a mouse/keyboard grab, mouse/keyboard events are sent to the grabbed widget. . Deals with a NULL widget for sending keyboard events (tries to find focused widget). BUG=none TEST=none Review URL: http://codereview.chromium.org/173392 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@24420 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/automation/ui_controls_linux.cc')
-rw-r--r--chrome/browser/automation/ui_controls_linux.cc83
1 files changed, 73 insertions, 10 deletions
diff --git a/chrome/browser/automation/ui_controls_linux.cc b/chrome/browser/automation/ui_controls_linux.cc
index bcaf6c5..9b5418e 100644
--- a/chrome/browser/automation/ui_controls_linux.cc
+++ b/chrome/browser/automation/ui_controls_linux.cc
@@ -13,6 +13,11 @@
#include "chrome/common/gtk_util.h"
#include "chrome/test/automation/automation_constants.h"
+#if defined(TOOLKIT_VIEWS)
+#include "views/view.h"
+#include "views/widget/widget.h"
+#endif
+
namespace {
guint32 EventTimeNow() {
@@ -33,18 +38,26 @@ class EventWaiter : public MessageLoopForUI::Observer {
// MessageLoop::Observer implementation:
virtual void WillProcessEvent(GdkEvent* event) {
- // No-op.
+ if (event->type == type_) {
+ // At the time we're invoked the event has not actually been processed.
+ // Use PostTask to make sure the event has been processed before
+ // notifying.
+ // NOTE: if processing a message results in running a nested message
+ // loop, then DidProcessEvent isn't immediately sent. As such, we do
+ // the processing in WillProcessEvent rather than DidProcessEvent.
+ MessageLoop::current()->PostTask(FROM_HERE, task_);
+ delete this;
+ }
}
virtual void DidProcessEvent(GdkEvent* event) {
- if (event->any.type == type_) {
- task_->Run();
- delete this;
- }
+ // No-op.
}
private:
- scoped_ptr<Task> task_;
+ // We pass ownership of task_ to MessageLoop when the corrent event is
+ // received.
+ Task *task_;
GdkEventType type_;
};
@@ -57,7 +70,10 @@ class ClickTask : public Task {
virtual ~ClickTask() {}
virtual void Run() {
- ui_controls::SendMouseEventsNotifyWhenDone(button_, state_, followup_);
+ if (followup_)
+ ui_controls::SendMouseEventsNotifyWhenDone(button_, state_, followup_);
+ else
+ ui_controls::SendMouseEvents(button_, state_);
}
private:
@@ -76,7 +92,25 @@ bool SendKeyPress(gfx::NativeWindow window,
GdkEvent* event = gdk_event_new(GDK_KEY_PRESS);
event->key.type = GDK_KEY_PRESS;
- event->key.window = GTK_WIDGET(window)->window;
+ GtkWidget* grab_widget = gtk_grab_get_current();
+ if (grab_widget) {
+ // If there is a grab, send all events to the grabbed widget.
+ event->key.window = grab_widget->window;
+ } else if (window) {
+ event->key.window = GTK_WIDGET(window)->window;
+ } else {
+ // No target was specified. Send the events to the focused window.
+ GList* windows = gtk_window_list_toplevels();
+ for (GList* element = windows; element; element = g_list_next(element)) {
+ GtkWindow* window = GTK_WINDOW(element->data);
+ if (gtk_window_is_active(window)) {
+ event->key.window = GTK_WIDGET(window)->window;
+ break;
+ }
+ }
+ g_list_free(windows);
+ }
+ DCHECK(event->key.window);
g_object_ref(event->key.window);
event->key.send_event = false;
event->key.time = EventTimeNow();
@@ -136,7 +170,15 @@ bool SendMouseEvents(MouseButton type, int state) {
event->button.time = EventTimeNow();
gint x, y;
- event->button.window = gdk_window_at_pointer(&x, &y);
+ GtkWidget* grab_widget = gtk_grab_get_current();
+ if (grab_widget) {
+ // If there is a grab, we need to target all events at it regardless of
+ // what widget the mouse is over.
+ event->button.window = grab_widget->window;
+ gdk_window_get_pointer(event->button.window, &x, &y, NULL);
+ } else {
+ event->button.window = gdk_window_at_pointer(&x, &y);
+ }
g_object_ref(event->button.window);
event->motion.x = x;
event->motion.y = y;
@@ -170,7 +212,18 @@ bool SendMouseEvents(MouseButton type, int state) {
bool SendMouseEventsNotifyWhenDone(MouseButton type, int state, Task* task) {
bool rv = SendMouseEvents(type, state);
- MessageLoop::current()->PostTask(FROM_HERE, task);
+ GdkEventType wait_type;
+ if (state & UP) {
+ wait_type = GDK_BUTTON_RELEASE;
+ } else {
+ if (type == LEFT)
+ wait_type = GDK_BUTTON_PRESS;
+ else if (type == MIDDLE)
+ wait_type = GDK_2BUTTON_PRESS;
+ else
+ wait_type = GDK_3BUTTON_PRESS;
+ }
+ new EventWaiter(task, wait_type);
return rv;
}
@@ -178,6 +231,15 @@ bool SendMouseClick(MouseButton type) {
return SendMouseEvents(type, UP | DOWN);
}
+#if defined(TOOLKIT_VIEWS)
+void MoveMouseToCenterAndPress(views::View* view, MouseButton button,
+ int state, Task* task) {
+ gfx::Point view_center(view->width() / 2, view->height() / 2);
+ views::View::ConvertPointToScreen(view, &view_center);
+ SendMouseMoveNotifyWhenDone(view_center.x(), view_center.y(),
+ new ClickTask(button, state, task));
+}
+#else
void MoveMouseToCenterAndPress(GtkWidget* widget,
MouseButton button,
int state,
@@ -187,5 +249,6 @@ void MoveMouseToCenterAndPress(GtkWidget* widget,
bounds.y() + bounds.height() / 2,
new ClickTask(button, state, task));
}
+#endif
} // namespace ui_controls