summaryrefslogtreecommitdiffstats
path: root/ui
diff options
context:
space:
mode:
authorerg@chromium.org <erg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-07-17 05:36:17 +0000
committererg@chromium.org <erg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-07-17 05:36:17 +0000
commit73669437db98cf422ddc43a04c38d55d2a5918e6 (patch)
tree43d8d42815a40118a3604b8268813e78cfe011e3 /ui
parentb03586b6a4d4ebeb942a9ee0794a2544a6ae7015 (diff)
downloadchromium_src-73669437db98cf422ddc43a04c38d55d2a5918e6.zip
chromium_src-73669437db98cf422ddc43a04c38d55d2a5918e6.tar.gz
chromium_src-73669437db98cf422ddc43a04c38d55d2a5918e6.tar.bz2
linux_aura: Change the mouse cursor during drag operations.
BUG=130806 Review URL: https://chromiumcodereview.appspot.com/19280005 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@211959 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ui')
-rw-r--r--ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11.cc32
-rw-r--r--ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11.h7
-rw-r--r--ui/views/widget/desktop_aura/desktop_native_cursor_manager.cc6
-rw-r--r--ui/views/widget/desktop_aura/desktop_native_cursor_manager.h3
-rw-r--r--ui/views/widget/desktop_aura/desktop_root_window_host_x11.cc12
-rw-r--r--ui/views/widget/desktop_aura/x11_desktop_window_move_client.cc2
-rw-r--r--ui/views/widget/desktop_aura/x11_whole_screen_move_loop.cc50
-rw-r--r--ui/views/widget/desktop_aura/x11_whole_screen_move_loop.h15
8 files changed, 93 insertions, 34 deletions
diff --git a/ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11.cc b/ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11.cc
index 953e2d7..26dbc68 100644
--- a/ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11.cc
+++ b/ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11.cc
@@ -18,6 +18,7 @@
#include "ui/base/events/event.h"
#include "ui/base/x/selection_utils.h"
#include "ui/base/x/x11_util.h"
+#include "ui/views/widget/desktop_aura/desktop_native_cursor_manager.h"
#include "ui/views/widget/desktop_aura/desktop_root_window_host_x11.h"
using aura::client::DragDropDelegate;
@@ -368,6 +369,7 @@ bool DesktopDragDropClientAuraX11::X11DragContext::Dispatch(
DesktopDragDropClientAuraX11::DesktopDragDropClientAuraX11(
views::DesktopRootWindowHostX11* root_window_host,
aura::RootWindow* root_window,
+ views::DesktopNativeCursorManager* cursor_manager,
Display* xdisplay,
::Window xwindow)
: move_loop_(this),
@@ -381,7 +383,10 @@ DesktopDragDropClientAuraX11::DesktopDragDropClientAuraX11(
source_current_window_(None),
drag_drop_in_progress_(false),
drag_operation_(0),
- resulting_operation_(0) {
+ resulting_operation_(0),
+ grab_cursor_(cursor_manager->GetInitializedCursor(ui::kCursorGrabbing)),
+ copy_grab_cursor_(cursor_manager->GetInitializedCursor(ui::kCursorCopy)),
+ move_grab_cursor_(cursor_manager->GetInitializedCursor(ui::kCursorMove)) {
DCHECK(g_live_client_map.find(xwindow) == g_live_client_map.end());
g_live_client_map.insert(std::make_pair(xwindow, this));
@@ -458,8 +463,24 @@ void DesktopDragDropClientAuraX11::OnXdndStatus(
DVLOG(1) << "XdndStatus";
unsigned long source_window = event.data.l[0];
- if (event.data.l[1] & 1)
- negotiated_operation_[source_window] = event.data.l[4];
+ int drag_operation = ui::DragDropTypes::DRAG_NONE;
+ if (event.data.l[1] & 1) {
+ ::Atom atom_operation = event.data.l[4];
+ negotiated_operation_[source_window] = atom_operation;
+ drag_operation = AtomToDragOperation(atom_operation);
+ }
+
+ switch (drag_operation) {
+ case ui::DragDropTypes::DRAG_COPY:
+ move_loop_.UpdateCursor(copy_grab_cursor_);
+ break;
+ case ui::DragDropTypes::DRAG_MOVE:
+ move_loop_.UpdateCursor(move_grab_cursor_);
+ break;
+ default:
+ move_loop_.UpdateCursor(grab_cursor_);
+ break;
+ }
// Note: event.data.[2,3] specify a rectangle. It is a request by the other
// window to not send further XdndPosition messages while the cursor is
@@ -469,9 +490,6 @@ void DesktopDragDropClientAuraX11::OnXdndStatus(
waiting_on_status_.erase(source_window);
- // TODO(erg): We should be using the response to try to update the cursor or
- // something.
-
if (ContainsKey(pending_drop_, source_window)) {
// We were waiting on the status message so we could send the XdndDrop.
SendXdndDrop(source_window);
@@ -569,7 +587,7 @@ int DesktopDragDropClientAuraX11::StartDragAndDrop(
// Windows has a specific method, DoDragDrop(), which performs the entire
// drag. We have to emulate this, so we spin off a nested runloop which will
// track all cursor movement and reroute events to a specific handler.
- move_loop_.RunMoveLoop(source_window);
+ move_loop_.RunMoveLoop(source_window, grab_cursor_);
source_provider_ = NULL;
drag_drop_in_progress_ = false;
diff --git a/ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11.h b/ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11.h
index 47b82061..b473a98 100644
--- a/ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11.h
+++ b/ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11.h
@@ -44,6 +44,7 @@ class SelectionFormatMap;
}
namespace views {
+class DesktopNativeCursorManager;
class DesktopRootWindowHostX11;
// Implements drag and drop on X11 for aura. On one side, this class takes raw
@@ -57,6 +58,7 @@ class VIEWS_EXPORT DesktopDragDropClientAuraX11
DesktopDragDropClientAuraX11(
views::DesktopRootWindowHostX11* root_window_host,
aura::RootWindow* root_window,
+ views::DesktopNativeCursorManager* cursor_manager,
Display* xdisplay,
::Window xwindow);
virtual ~DesktopDragDropClientAuraX11();
@@ -216,6 +218,11 @@ class VIEWS_EXPORT DesktopDragDropClientAuraX11
// window responds to an XdndStatus.
std::map< ::Window, ::Atom> negotiated_operation_;
+ // We use these cursors while dragging.
+ gfx::NativeCursor grab_cursor_;
+ gfx::NativeCursor copy_grab_cursor_;
+ gfx::NativeCursor move_grab_cursor_;
+
static std::map< ::Window, DesktopDragDropClientAuraX11*> g_live_client_map;
DISALLOW_COPY_AND_ASSIGN(DesktopDragDropClientAuraX11);
diff --git a/ui/views/widget/desktop_aura/desktop_native_cursor_manager.cc b/ui/views/widget/desktop_aura/desktop_native_cursor_manager.cc
index 856738f..a9b902d 100644
--- a/ui/views/widget/desktop_aura/desktop_native_cursor_manager.cc
+++ b/ui/views/widget/desktop_aura/desktop_native_cursor_manager.cc
@@ -23,6 +23,12 @@ DesktopNativeCursorManager::DesktopNativeCursorManager(
DesktopNativeCursorManager::~DesktopNativeCursorManager() {
}
+gfx::NativeCursor DesktopNativeCursorManager::GetInitializedCursor(int type) {
+ gfx::NativeCursor cursor(type);
+ cursor_loader_->SetPlatformCursor(&cursor);
+ return cursor;
+}
+
void DesktopNativeCursorManager::SetDisplay(
const gfx::Display& display,
views::corewm::NativeCursorManagerDelegate* delegate) {
diff --git a/ui/views/widget/desktop_aura/desktop_native_cursor_manager.h b/ui/views/widget/desktop_aura/desktop_native_cursor_manager.h
index cbee0c4..f6a800b 100644
--- a/ui/views/widget/desktop_aura/desktop_native_cursor_manager.h
+++ b/ui/views/widget/desktop_aura/desktop_native_cursor_manager.h
@@ -35,6 +35,9 @@ class VIEWS_EXPORT DesktopNativeCursorManager
scoped_ptr<DesktopCursorLoaderUpdater> cursor_loader_updater);
virtual ~DesktopNativeCursorManager();
+ // Builds a cursor and sets the internal platform representation.
+ gfx::NativeCursor GetInitializedCursor(int type);
+
private:
// Overridden from views::corewm::NativeCursorManager:
virtual void SetDisplay(
diff --git a/ui/views/widget/desktop_aura/desktop_root_window_host_x11.cc b/ui/views/widget/desktop_aura/desktop_root_window_host_x11.cc
index 0ff8476..ca4fb27 100644
--- a/ui/views/widget/desktop_aura/desktop_root_window_host_x11.cc
+++ b/ui/views/widget/desktop_aura/desktop_root_window_host_x11.cc
@@ -311,13 +311,15 @@ aura::RootWindow* DesktopRootWindowHostX11::InitRootWindow(
aura::client::SetDispatcherClient(root_window_,
dispatcher_client_.get());
+ views::DesktopNativeCursorManager* desktop_native_cursor_manager =
+ new views::DesktopNativeCursorManager(
+ root_window_,
+ scoped_ptr<DesktopCursorLoaderUpdater>(
+ new DesktopCursorLoaderUpdaterAuraX11));
cursor_client_.reset(
new views::corewm::CursorManager(
scoped_ptr<corewm::NativeCursorManager>(
- new views::DesktopNativeCursorManager(
- root_window_,
- scoped_ptr<DesktopCursorLoaderUpdater>(
- new DesktopCursorLoaderUpdaterAuraX11)))));
+ desktop_native_cursor_manager)));
aura::client::SetCursorClient(root_window_,
cursor_client_.get());
@@ -328,7 +330,7 @@ aura::RootWindow* DesktopRootWindowHostX11::InitRootWindow(
desktop_native_widget_aura_->InstallInputMethodEventFilter(root_window_);
drag_drop_client_.reset(new DesktopDragDropClientAuraX11(
- this, root_window_, xdisplay_, xwindow_));
+ this, root_window_, desktop_native_cursor_manager, xdisplay_, xwindow_));
aura::client::SetDragDropClient(root_window_, drag_drop_client_.get());
// TODO(erg): Unify this code once the other consumer goes away.
diff --git a/ui/views/widget/desktop_aura/x11_desktop_window_move_client.cc b/ui/views/widget/desktop_aura/x11_desktop_window_move_client.cc
index 986e945..d28de21 100644
--- a/ui/views/widget/desktop_aura/x11_desktop_window_move_client.cc
+++ b/ui/views/widget/desktop_aura/x11_desktop_window_move_client.cc
@@ -52,7 +52,7 @@ aura::client::WindowMoveResult X11DesktopWindowMoveClient::RunMoveLoop(
window_offset_ = drag_offset;
root_window_ = source->GetRootWindow();
- bool success = move_loop_.RunMoveLoop(source);
+ bool success = move_loop_.RunMoveLoop(source, root_window_->last_cursor());
return success ? aura::client::MOVE_SUCCESSFUL : aura::client::MOVE_CANCELED;
}
diff --git a/ui/views/widget/desktop_aura/x11_whole_screen_move_loop.cc b/ui/views/widget/desktop_aura/x11_whole_screen_move_loop.cc
index b38534f..d04dd88 100644
--- a/ui/views/widget/desktop_aura/x11_whole_screen_move_loop.cc
+++ b/ui/views/widget/desktop_aura/x11_whole_screen_move_loop.cc
@@ -59,7 +59,8 @@ bool X11WholeScreenMoveLoop::Dispatch(const base::NativeEvent& event) {
////////////////////////////////////////////////////////////////////////////////
// DesktopRootWindowHostLinux, aura::client::WindowMoveClient implementation:
-bool X11WholeScreenMoveLoop::RunMoveLoop(aura::Window* source) {
+bool X11WholeScreenMoveLoop::RunMoveLoop(aura::Window* source,
+ gfx::NativeCursor cursor) {
DCHECK(!in_move_loop_); // Can only handle one nested loop at a time.
in_move_loop_ = true;
@@ -90,24 +91,8 @@ bool X11WholeScreenMoveLoop::RunMoveLoop(aura::Window* source) {
base::MessagePumpAuraX11::Current()->BlockUntilWindowMapped(
grab_input_window_);
- XGrabServer(display);
- XUngrabPointer(display, CurrentTime);
- int ret = XGrabPointer(
- display,
- grab_input_window_,
- False,
- ButtonPressMask | ButtonReleaseMask | PointerMotionMask,
- GrabModeAsync,
- GrabModeAsync,
- None,
- None,
- CurrentTime);
- XUngrabServer(display);
- if (ret != GrabSuccess) {
- DLOG(ERROR) << "Grabbing new tab for dragging failed: "
- << ui::GetX11ErrorString(display, ret);
+ if (!GrabPointerWithCursor(cursor))
return false;
- }
base::MessageLoopForUI* loop = base::MessageLoopForUI::current();
base::MessageLoop::ScopedNestableTaskAllower allow_nested(loop);
@@ -117,6 +102,11 @@ bool X11WholeScreenMoveLoop::RunMoveLoop(aura::Window* source) {
return true;
}
+void X11WholeScreenMoveLoop::UpdateCursor(gfx::NativeCursor cursor) {
+ DCHECK(in_move_loop_);
+ GrabPointerWithCursor(cursor);
+}
+
void X11WholeScreenMoveLoop::EndMoveLoop() {
if (!in_move_loop_)
return;
@@ -138,4 +128,28 @@ void X11WholeScreenMoveLoop::EndMoveLoop() {
quit_closure_.Run();
}
+bool X11WholeScreenMoveLoop::GrabPointerWithCursor(gfx::NativeCursor cursor) {
+ Display* display = base::MessagePumpAuraX11::GetDefaultXDisplay();
+ XGrabServer(display);
+ XUngrabPointer(display, CurrentTime);
+ int ret = XGrabPointer(
+ display,
+ grab_input_window_,
+ False,
+ ButtonPressMask | ButtonReleaseMask | PointerMotionMask,
+ GrabModeAsync,
+ GrabModeAsync,
+ None,
+ cursor.platform(),
+ CurrentTime);
+ XUngrabServer(display);
+ if (ret != GrabSuccess) {
+ DLOG(ERROR) << "Grabbing new tab for dragging failed: "
+ << ui::GetX11ErrorString(display, ret);
+ return false;
+ }
+
+ return true;
+}
+
} // namespace views
diff --git a/ui/views/widget/desktop_aura/x11_whole_screen_move_loop.h b/ui/views/widget/desktop_aura/x11_whole_screen_move_loop.h
index 1a01db0..97db5f8 100644
--- a/ui/views/widget/desktop_aura/x11_whole_screen_move_loop.h
+++ b/ui/views/widget/desktop_aura/x11_whole_screen_move_loop.h
@@ -7,6 +7,7 @@
#include "base/compiler_specific.h"
#include "base/message_loop.h"
+#include "ui/gfx/native_widget_types.h"
#include "ui/views/widget/desktop_aura/x11_whole_screen_move_loop_delegate.h"
namespace aura {
@@ -25,14 +26,22 @@ class X11WholeScreenMoveLoop : public base::MessageLoop::Dispatcher {
// Overridden from base::MessageLoop::Dispatcher:
virtual bool Dispatch(const base::NativeEvent& event) OVERRIDE;
- // Runs the nested message loop. Returns true if there we were able to grab
- // the pointer and run the move loop.
- bool RunMoveLoop(aura::Window* window);
+ // Runs the nested message loop. While the mouse is grabbed, use |cursor| as
+ // the mouse cursor. Returns true if there we were able to grab the pointer
+ // and run the move loop.
+ bool RunMoveLoop(aura::Window* window, gfx::NativeCursor cursor);
+
+ // Updates the cursor while the move loop is running.
+ void UpdateCursor(gfx::NativeCursor cursor);
// Ends the RunMoveLoop() that's currently in progress.
void EndMoveLoop();
private:
+ // Grabs the pointer, setting the mouse cursor to |cursor|. Returns true if
+ // the grab was successful.
+ bool GrabPointerWithCursor(gfx::NativeCursor cursor);
+
X11WholeScreenMoveLoopDelegate* delegate_;
// Are we running a nested message loop from RunMoveLoop()?