Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(816)

Unified Diff: chrome/browser/automation/automation_provider_gtk.cc

Issue 218017: GTK: First cut at tab dragging automation.... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: comments Created 11 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | chrome/browser/automation/ui_controls_linux.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/browser/automation/automation_provider_gtk.cc
===================================================================
--- chrome/browser/automation/automation_provider_gtk.cc (revision 26890)
+++ chrome/browser/automation/automation_provider_gtk.cc (working copy)
@@ -4,8 +4,11 @@
#include "chrome/browser/automation/automation_provider.h"
+#include <gtk/gtk.h>
+
#include "base/gfx/point.h"
#include "base/gfx/rect.h"
+#include "chrome/browser/automation/ui_controls.h"
#include "chrome/browser/gtk/browser_window_gtk.h"
#include "chrome/browser/gtk/view_id_util.h"
#include "chrome/common/gtk_util.h"
@@ -94,14 +97,123 @@
NOTIMPLEMENTED();
}
+// This task sends a WindowDragResponse message with the appropriate
+// routing ID to the automation proxy. This is implemented as a task so that
+// we know that the mouse events (and any tasks that they spawn on the message
+// loop) have been processed by the time this is sent.
+class WindowDragResponseTask : public Task {
+ public:
+ WindowDragResponseTask(AutomationProvider* provider,
+ IPC::Message* reply_message)
+ : provider_(provider),
+ reply_message_(reply_message) {
+ DCHECK(reply_message_);
+ DCHECK(provider);
Paweł Hajdan Jr. 2009/09/24 18:04:58 very-small-nit: Please be consistent and check thi
+ }
+
+ virtual ~WindowDragResponseTask() {
+ }
+
+ virtual void Run() {
+ AutomationMsg_WindowDrag::WriteReplyParams(reply_message_, true);
+ provider_->Send(reply_message_);
+ }
+
+ private:
+ AutomationProvider* provider_;
+ IPC::Message* reply_message_;
+
+ DISALLOW_COPY_AND_ASSIGN(WindowDragResponseTask);
+};
+
+// A task that just runs a SendMouseEvent and performs another task when done.
+class MouseEventTask : public Task {
+ public:
+ MouseEventTask(Task* next_task, ui_controls::MouseButtonState state)
+ : next_task_(next_task),
+ state_(state) {}
+
+ virtual ~MouseEventTask() {
+ }
+
+ virtual void Run() {
+ ui_controls::SendMouseEventsNotifyWhenDone(ui_controls::LEFT, state_,
+ next_task_);
+ }
+
+ private:
+ // The task to execute when we are done.
+ Task* next_task_;
+
+ // Mouse press or mouse release.
+ ui_controls::MouseButtonState state_;
+
+ DISALLOW_COPY_AND_ASSIGN(MouseEventTask);
+};
+
+// A task that just runs a SendMouseMove and performs another task when done.
+class MouseMoveTask : public Task {
+ public:
+ MouseMoveTask(Task* next_task, int absolute_x, int absolute_y)
+ : next_task_(next_task),
+ x_(absolute_x),
+ y_(absolute_y) {
+ }
+
+ virtual ~MouseMoveTask() {
+ }
+
+ virtual void Run() {
+ ui_controls::SendMouseMoveNotifyWhenDone(x_, y_, next_task_);
+ }
+
+ private:
+ // The task to execute when we are done.
+ Task* next_task_;
+
+ // Coordinates of the press.
+ int x_;
+ int y_;
+
+ DISALLOW_COPY_AND_ASSIGN(MouseMoveTask);
+};
+
void AutomationProvider::WindowSimulateDrag(int handle,
std::vector<gfx::Point> drag_path,
int flags,
bool press_escape_en_route,
IPC::Message* reply_message) {
- NOTIMPLEMENTED();
- AutomationMsg_WindowDrag::WriteReplyParams(reply_message, false);
- Send(reply_message);
+ // TODO(estade): don't ignore |flags| or |escape_en_route|.
+ gfx::NativeWindow window =
+ browser_tracker_->GetResource(handle)->window()->GetNativeHandle();
+ if (window && (drag_path.size() > 1)) {
+ int x, y;
+ gdk_window_get_position(GTK_WIDGET(window)->window, &x, &y);
+
+ // Create a nested stack of tasks to run.
+ Task* next_task = new WindowDragResponseTask(this, reply_message);
+ next_task = new MouseEventTask(next_task, ui_controls::UP);
+ next_task = new MouseEventTask(next_task, ui_controls::UP);
+ for (size_t i = drag_path.size() - 1; i > 0; --i) {
+ // Smooth out the mouse movements by adding intermediate points. This
+ // better simulates a real user drag.
+ int dest_x = drag_path[i].x() + x;
+ int dest_y = drag_path[i].y() + y;
+ int half_step_x = (dest_x + drag_path[i - 1].x() + x) / 2;
+ int half_step_y = (dest_y + drag_path[i - 1].y() + y) / 2;
+
+ next_task = new MouseMoveTask(next_task, dest_x, dest_y);
+ next_task = new MouseMoveTask(next_task, half_step_x, half_step_y);
+ }
+ next_task = new MouseEventTask(next_task, ui_controls::DOWN);
+
+ ui_controls::SendMouseMoveNotifyWhenDone(x + drag_path[0].x(),
+ y + drag_path[0].y(),
+ next_task);
+ } else {
+ AutomationMsg_WindowDrag::WriteReplyParams(reply_message, false);
+ Send(reply_message);
+ }
}
void AutomationProvider::TerminateSession(int handle, bool* success) {
« no previous file with comments | « no previous file | chrome/browser/automation/ui_controls_linux.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698