diff options
author | jianli@chromium.org <jianli@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-01-15 18:49:58 +0000 |
---|---|---|
committer | jianli@chromium.org <jianli@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-01-15 18:49:58 +0000 |
commit | 6aa4a1c041ca9bd2c3087c3c059a87193b1a82e1 (patch) | |
tree | 8e833c393312e866250077c15bc1d90464fe99d7 /base | |
parent | 963dfb5a05c5b0e3fa8ed74d803f01cb10fd455e (diff) | |
download | chromium_src-6aa4a1c041ca9bd2c3087c3c059a87193b1a82e1.zip chromium_src-6aa4a1c041ca9bd2c3087c3c059a87193b1a82e1.tar.gz chromium_src-6aa4a1c041ca9bd2c3087c3c059a87193b1a82e1.tar.bz2 |
Support dragging a virtual file out of the browser.
BUG=none
TEST=none
Review URL: http://codereview.chromium.org/351029
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@36378 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'base')
-rw-r--r-- | base/base_drag_source.cc | 12 | ||||
-rw-r--r-- | base/base_drag_source.h | 6 | ||||
-rw-r--r-- | base/base_drop_target.cc | 11 | ||||
-rw-r--r-- | base/base_drop_target.h | 9 | ||||
-rw-r--r-- | base/file_util.h | 9 | ||||
-rw-r--r-- | base/file_util_win.cc | 9 | ||||
-rw-r--r-- | base/message_loop_unittest.cc | 43 | ||||
-rw-r--r-- | base/message_pump_win.cc | 3 | ||||
-rw-r--r-- | base/message_pump_win.h | 3 |
9 files changed, 86 insertions, 19 deletions
diff --git a/base/base_drag_source.cc b/base/base_drag_source.cc index bc81395..9b335a7 100644 --- a/base/base_drag_source.cc +++ b/base/base_drag_source.cc @@ -7,7 +7,7 @@ /////////////////////////////////////////////////////////////////////////////// // BaseDragSource, public: -BaseDragSource::BaseDragSource() : ref_count_(0), cancel_drag_(false) { +BaseDragSource::BaseDragSource() : cancel_drag_(false) { } /////////////////////////////////////////////////////////////////////////////// @@ -51,13 +51,11 @@ HRESULT BaseDragSource::QueryInterface(const IID& iid, void** object) { } ULONG BaseDragSource::AddRef() { - return ++ref_count_; + base::RefCountedThreadSafe<BaseDragSource>::AddRef(); + return 0; } ULONG BaseDragSource::Release() { - if (--ref_count_ == 0) { - delete this; - return 0U; - } - return ref_count_; + base::RefCountedThreadSafe<BaseDragSource>::Release(); + return 0; } diff --git a/base/base_drag_source.h b/base/base_drag_source.h index 3a4a94c..2ea531f 100644 --- a/base/base_drag_source.h +++ b/base/base_drag_source.h @@ -8,6 +8,7 @@ #include <objidl.h> #include "base/basictypes.h" +#include "base/ref_counted.h" /////////////////////////////////////////////////////////////////////////////// // @@ -18,7 +19,8 @@ // system. This object tells Windows whether or not the drag should continue, // and supplies the appropriate cursors. // -class BaseDragSource : public IDropSource { +class BaseDragSource : public IDropSource, + public base::RefCountedThreadSafe<BaseDragSource> { public: BaseDragSource(); virtual ~BaseDragSource() { } @@ -45,8 +47,6 @@ class BaseDragSource : public IDropSource { virtual void OnDragSourceMove() { } private: - LONG ref_count_; - // Set to true if we want to cancel the drag operation. bool cancel_drag_; diff --git a/base/base_drop_target.cc b/base/base_drop_target.cc index 77fe675..1ee878f 100644 --- a/base/base_drop_target.cc +++ b/base/base_drop_target.cc @@ -15,7 +15,7 @@ int32 BaseDropTarget::drag_identity_ = 0; BaseDropTarget::BaseDropTarget(HWND hwnd) : hwnd_(hwnd), - suspend_(false), + suspended_(false), ref_count_(0) { DCHECK(hwnd); HRESULT result = RegisterDragDrop(hwnd, this); @@ -50,7 +50,7 @@ HRESULT BaseDropTarget::DragEnter(IDataObject* data_object, } // You can't drag and drop within the same HWND. - if (suspend_) { + if (suspended_) { *effect = DROPEFFECT_NONE; return S_OK; } @@ -73,7 +73,7 @@ HRESULT BaseDropTarget::DragOver(DWORD key_state, if (drop_helper) drop_helper->DragOver(reinterpret_cast<POINT*>(&cursor_position), *effect); - if (suspend_) { + if (suspended_) { *effect = DROPEFFECT_NONE; return S_OK; } @@ -89,6 +89,9 @@ HRESULT BaseDropTarget::DragLeave() { if (drop_helper) drop_helper->DragLeave(); + if (suspended_) + return S_OK; + OnDragLeave(current_data_object_); current_data_object_ = NULL; @@ -106,7 +109,7 @@ HRESULT BaseDropTarget::Drop(IDataObject* data_object, reinterpret_cast<POINT*>(&cursor_position), *effect); } - if (suspend_) { + if (suspended_) { *effect = DROPEFFECT_NONE; return S_OK; } diff --git a/base/base_drop_target.h b/base/base_drop_target.h index cf63be28..8be0d36 100644 --- a/base/base_drop_target.h +++ b/base/base_drop_target.h @@ -26,12 +26,13 @@ class BaseDropTarget : public IDropTarget { explicit BaseDropTarget(HWND hwnd); virtual ~BaseDropTarget(); - // When suspend is set to |true|, the drop target does not receive drops from - // drags initiated within the owning HWND. + // When suspended is set to |true|, the drop target does not receive drops + // from drags initiated within the owning HWND. // TODO(beng): (http://b/1085385) figure out how we will handle legitimate // drag-drop operations within the same HWND, such as dragging // selected text to an edit field. - void set_suspend(bool suspend) { suspend_ = suspend; } + bool suspended() const { return suspended_; } + void set_suspended(bool suspended) { suspended_ = suspended; } // IDropTarget implementation: HRESULT __stdcall DragEnter(IDataObject* data_object, @@ -120,7 +121,7 @@ class BaseDropTarget : public IDropTarget { // Whether or not we are currently processing drag notifications for drags // initiated in this window. - bool suspend_; + bool suspended_; LONG ref_count_; diff --git a/base/file_util.h b/base/file_util.h index 543a86c..efa4633 100644 --- a/base/file_util.h +++ b/base/file_util.h @@ -128,6 +128,15 @@ bool Delete(const FilePath& path, bool recursive); // Deprecated temporary compatibility function. bool Delete(const std::wstring& path, bool recursive); +#if defined(OS_WIN) +// Schedules to delete the given path, whether it's a file or a directory, until +// the operating system is restarted. +// Note: +// 1) The file/directory to be deleted should exist in a temp folder. +// 2) The directory to be deleted must be empty. +bool DeleteAfterReboot(const FilePath& path); +#endif + // Moves the given path, whether it's a file or a directory. // If a simple rename is not possible, such as in the case where the paths are // on different volumes, this will attempt to copy and delete. Returns diff --git a/base/file_util_win.cc b/base/file_util_win.cc index e066422..7c3de4d 100644 --- a/base/file_util_win.cc +++ b/base/file_util_win.cc @@ -98,6 +98,15 @@ bool Delete(const FilePath& path, bool recursive) { return (err == 0 || err == ERROR_FILE_NOT_FOUND); } +bool DeleteAfterReboot(const FilePath& path) { + if (path.value().length() >= MAX_PATH) + return false; + + return MoveFileEx(path.value().c_str(), NULL, + MOVEFILE_DELAY_UNTIL_REBOOT | + MOVEFILE_REPLACE_EXISTING) != FALSE; +} + bool Move(const FilePath& from_path, const FilePath& to_path) { // NOTE: I suspect we could support longer paths, but that would involve // analyzing all our usage of files. diff --git a/base/message_loop_unittest.cc b/base/message_loop_unittest.cc index 74491ce..00a1dfe 100644 --- a/base/message_loop_unittest.cc +++ b/base/message_loop_unittest.cc @@ -1107,7 +1107,12 @@ class DispatcherImpl : public MessageLoopForUI::Dispatcher { virtual bool Dispatch(const MSG& msg) { ::TranslateMessage(&msg); ::DispatchMessage(&msg); - return (++dispatch_count_ != 2); + // Do not count WM_TIMER since it is not what we post and it will cause + // flakiness. + if (msg.message != WM_TIMER) + ++dispatch_count_; + // We treat WM_LBUTTONUP as the last message. + return msg.message != WM_LBUTTONUP; } int dispatch_count_; @@ -1130,6 +1135,37 @@ void RunTest_Dispatcher(MessageLoop::Type message_loop_type) { ASSERT_EQ(2, dispatcher.dispatch_count_); } +LRESULT CALLBACK MsgFilterProc(int code, WPARAM wparam, LPARAM lparam) { + if (code == base::MessagePumpForUI::kMessageFilterCode) { + MSG* msg = reinterpret_cast<MSG*>(lparam); + if (msg->message == WM_LBUTTONDOWN) + return TRUE; + } + return FALSE; +} + +void RunTest_DispatcherWithMessageHook(MessageLoop::Type message_loop_type) { + MessageLoop loop(message_loop_type); + + class MyTask : public Task { + public: + virtual void Run() { + PostMessage(NULL, WM_LBUTTONDOWN, 0, 0); + PostMessage(NULL, WM_LBUTTONUP, 'A', 0); + } + }; + Task* task = new MyTask(); + MessageLoop::current()->PostDelayedTask(FROM_HERE, task, 100); + HHOOK msg_hook = SetWindowsHookEx(WH_MSGFILTER, + MsgFilterProc, + NULL, + GetCurrentThreadId()); + DispatcherImpl dispatcher; + MessageLoopForUI::current()->Run(&dispatcher); + ASSERT_EQ(1, dispatcher.dispatch_count_); + UnhookWindowsHookEx(msg_hook); +} + class TestIOHandler : public MessageLoopForIO::IOHandler { public: TestIOHandler(const wchar_t* name, HANDLE signal, bool wait); @@ -1423,6 +1459,11 @@ TEST(MessageLoopTest, Dispatcher) { RunTest_Dispatcher(MessageLoop::TYPE_UI); } +TEST(MessageLoopTest, DispatcherWithMessageHook) { + // This test requires a UI loop + RunTest_DispatcherWithMessageHook(MessageLoop::TYPE_UI); +} + TEST(MessageLoopTest, IOHandler) { RunTest_IOHandler(); } diff --git a/base/message_pump_win.cc b/base/message_pump_win.cc index 737676c..f40c872 100644 --- a/base/message_pump_win.cc +++ b/base/message_pump_win.cc @@ -351,6 +351,9 @@ bool MessagePumpForUI::ProcessMessageHelper(const MSG& msg) { if (msg.message == kMsgHaveWork && msg.hwnd == message_hwnd_) return ProcessPumpReplacementMessage(); + if (CallMsgFilter(const_cast<MSG*>(&msg), kMessageFilterCode)) + return true; + WillProcessMessage(msg); if (state_->dispatcher) { diff --git a/base/message_pump_win.h b/base/message_pump_win.h index 63222a8..e6ea233 100644 --- a/base/message_pump_win.h +++ b/base/message_pump_win.h @@ -157,6 +157,9 @@ class MessagePumpWin : public MessagePump { // class MessagePumpForUI : public MessagePumpWin { public: + // The application-defined code passed to the hook procedure. + static const int kMessageFilterCode = 0x5001; + MessagePumpForUI(); virtual ~MessagePumpForUI(); |