diff options
author | erg@chromium.org <erg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-07-17 05:36:17 +0000 |
---|---|---|
committer | erg@chromium.org <erg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-07-17 05:36:17 +0000 |
commit | 73669437db98cf422ddc43a04c38d55d2a5918e6 (patch) | |
tree | 43d8d42815a40118a3604b8268813e78cfe011e3 /ui | |
parent | b03586b6a4d4ebeb942a9ee0794a2544a6ae7015 (diff) | |
download | chromium_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')
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()? |