diff options
author | Ben Murdoch <benm@google.com> | 2014-04-01 10:55:12 +0100 |
---|---|---|
committer | Ben Murdoch <benm@google.com> | 2014-04-01 10:55:12 +0100 |
commit | 4ad1aa43a48567659193a298fad74f55e00b3dd9 (patch) | |
tree | b98c2a945dbec61aeb9edef5e371f905e7ab5b37 /ui | |
parent | e92e8c41ae2718e381c0796a2c0b115a7d017a21 (diff) | |
download | chromium_org-4ad1aa43a48567659193a298fad74f55e00b3dd9.tar.gz |
Merge from Chromium at DEPS revision 260540
This commit was generated by merge_to_master.py.
Change-Id: I10b8e4931992bb84eb4da800a337bbd0a52f6588
Diffstat (limited to 'ui')
38 files changed, 628 insertions, 370 deletions
diff --git a/ui/app_list/views/app_list_folder_view.cc b/ui/app_list/views/app_list_folder_view.cc index d51d67ff90..b544f309c5 100644 --- a/ui/app_list/views/app_list_folder_view.cc +++ b/ui/app_list/views/app_list_folder_view.cc @@ -262,8 +262,11 @@ void AppListFolderView::ReparentItem( void AppListFolderView::DispatchDragEventForReparent( AppsGridView::Pointer pointer, - const ui::LocatedEvent& event) { - container_view_->apps_grid_view()->UpdateDragFromReparentItem(pointer, event); + const gfx::Point& drag_point_in_folder_grid) { + AppsGridView* root_grid = container_view_->apps_grid_view(); + gfx::Point drag_point_in_root_grid = drag_point_in_folder_grid; + ConvertPointToTarget(items_grid_view_, root_grid, &drag_point_in_root_grid); + root_grid->UpdateDragFromReparentItem(pointer, drag_point_in_folder_grid); } void AppListFolderView::DispatchEndDragEventForReparent( diff --git a/ui/app_list/views/app_list_folder_view.h b/ui/app_list/views/app_list_folder_view.h index b6d960051a..e34107f517 100644 --- a/ui/app_list/views/app_list_folder_view.h +++ b/ui/app_list/views/app_list_folder_view.h @@ -91,9 +91,9 @@ class AppListFolderView : public views::View, virtual void ReparentItem(AppListItemView* original_drag_view, const gfx::Point& drag_point_in_folder_grid) OVERRIDE; - virtual void DispatchDragEventForReparent(AppsGridView::Pointer pointer, - const ui::LocatedEvent& event) - OVERRIDE; + virtual void DispatchDragEventForReparent( + AppsGridView::Pointer pointer, + const gfx::Point& drag_point_in_folder_grid) OVERRIDE; virtual void DispatchEndDragEventForReparent( bool events_forwarded_to_drag_drop_host) OVERRIDE; virtual bool IsPointOutsideOfFolderBoundary(const gfx::Point& point) OVERRIDE; diff --git a/ui/app_list/views/app_list_main_view.cc b/ui/app_list/views/app_list_main_view.cc index f82236482d..28c06a10a8 100644 --- a/ui/app_list/views/app_list_main_view.cc +++ b/ui/app_list/views/app_list_main_view.cc @@ -20,6 +20,7 @@ #include "ui/app_list/pagination_model.h" #include "ui/app_list/search_box_model.h" #include "ui/app_list/views/app_list_item_view.h" +#include "ui/app_list/views/apps_container_view.h" #include "ui/app_list/views/contents_switcher_view.h" #include "ui/app_list/views/contents_view.h" #include "ui/app_list/views/search_box_view.h" @@ -137,6 +138,13 @@ void AppListMainView::ShowAppListWhenReady() { this, &AppListMainView::OnIconLoadingWaitTimer); } +void AppListMainView::ResetForShow() { + contents_view_->apps_container_view()->ResetForShowApps(); + // We clear the search when hiding so when app list appears it is not showing + // search results. + search_box_view_->ClearSearch(); +} + void AppListMainView::Close() { icon_loading_wait_timer_.Stop(); contents_view_->CancelDrag(); diff --git a/ui/app_list/views/app_list_main_view.h b/ui/app_list/views/app_list_main_view.h index 7cfa116e34..caa83b9061 100644 --- a/ui/app_list/views/app_list_main_view.h +++ b/ui/app_list/views/app_list_main_view.h @@ -45,6 +45,8 @@ class APP_LIST_EXPORT AppListMainView : public views::View, void ShowAppListWhenReady(); + void ResetForShow(); + void Close(); void Prerender(); diff --git a/ui/app_list/views/app_list_view.cc b/ui/app_list/views/app_list_view.cc index 38a61d3e29..a66f34b231 100644 --- a/ui/app_list/views/app_list_view.cc +++ b/ui/app_list/views/app_list_view.cc @@ -439,10 +439,8 @@ void AppListView::OnWidgetVisibilityChanged(views::Widget* widget, if (widget != GetWidget()) return; - // We clear the search when hiding so the next time the app list appears it is - // not showing search results. if (!visible) - app_list_main_view_->search_box_view()->ClearSearch(); + app_list_main_view_->ResetForShow(); // Whether we need to signin or not may have changed since last time we were // shown. diff --git a/ui/app_list/views/apps_container_view.cc b/ui/app_list/views/apps_container_view.cc index a56b3a925c..a6843928fd 100644 --- a/ui/app_list/views/apps_container_view.cc +++ b/ui/app_list/views/apps_container_view.cc @@ -66,6 +66,12 @@ void AppsContainerView::ShowApps(AppListFolderItem* folder_item) { true); /* show apps with animation */ } +void AppsContainerView::ResetForShowApps() { + SetShowState(SHOW_APPS, false /* show apps without animation */); + folder_background_view_->UpdateFolderContainerBubble( + FolderBackgroundView::NO_BUBBLE); +} + void AppsContainerView::SetDragAndDropHostOfCurrentAppList( ApplicationDragAndDropHost* drag_and_drop_host) { apps_grid_view()->SetDragAndDropHostOfCurrentAppList(drag_and_drop_host); @@ -145,7 +151,7 @@ void AppsContainerView::SetShowState(ShowState show_state, apps_grid_view_->ScheduleShowHideAnimation(true); } else { app_list_folder_view_->HideViewImmediately(); - apps_grid_view_->SetVisible(true); + apps_grid_view_->ResetForShowApps(); } break; case SHOW_ACTIVE_FOLDER: diff --git a/ui/app_list/views/apps_container_view.h b/ui/app_list/views/apps_container_view.h index 1c8a9131a6..1be5d3dd3a 100644 --- a/ui/app_list/views/apps_container_view.h +++ b/ui/app_list/views/apps_container_view.h @@ -43,6 +43,12 @@ class AppsContainerView : public views::View, // a folder view with |folder_item|. If |folder_item| is NULL skips animation. void ShowApps(AppListFolderItem* folder_item); + // Resets the app list to a state where it shows the main grid view. This is + // called when the user opens the launcher for the first time or when the user + // hides and then shows it. This is necessary because we only hide and show + // the launcher on Windows and Linux so we need to reset to a fresh state. + void ResetForShowApps(); + // Sets |drag_and_drop_host_| for the current app list in both // app_list_folder_view_ and root level apps_grid_view_. void SetDragAndDropHostOfCurrentAppList( diff --git a/ui/app_list/views/apps_grid_view.cc b/ui/app_list/views/apps_grid_view.cc index 63f817c939..197a65f000 100644 --- a/ui/app_list/views/apps_grid_view.cc +++ b/ui/app_list/views/apps_grid_view.cc @@ -367,6 +367,17 @@ void AppsGridView::SetLayout(int icon_size, int cols, int rows_per_page) { kTopPadding, kLeftRightPadding, 0, kLeftRightPadding)); } +void AppsGridView::ResetForShowApps() { + activated_item_view_ = NULL; + layer()->SetOpacity(1.0f); + SetVisible(true); + // Set all views to visible in case they weren't made visible again by an + // incomplete animation. + for (int i = 0; i < view_model_.view_size(); ++i) { + view_model_.view_at(i)->SetVisible(true); + } +} + void AppsGridView::SetModel(AppListModel* model) { if (model_) model_->RemoveObserver(this); @@ -462,6 +473,10 @@ void AppsGridView::StartSettingUpSynchronousDrag() { if (drag_and_drop_host_) return; + // Never create a second synchronous drag if the drag started in a folder. + if (IsDraggingForReparentInRootLevelGridView()) + return; + delegate_->GetShortcutPathForApp( drag_view_->item()->id(), base::Bind(&AppsGridView::OnGotShortcutPath, base::Unretained(this))); @@ -493,9 +508,6 @@ bool AppsGridView::UpdateDragFromItem(Pointer pointer, const ui::LocatedEvent& event) { DCHECK(drag_view_); - if (folder_delegate_) - UpdateDragStateInsideFolder(pointer, event); - gfx::Point drag_point_in_grid_view; ExtractDragLocation(event, &drag_point_in_grid_view); UpdateDrag(pointer, drag_point_in_grid_view); @@ -513,6 +525,9 @@ bool AppsGridView::UpdateDragFromItem(Pointer pointer, } void AppsGridView::UpdateDrag(Pointer pointer, const gfx::Point& point) { + if (folder_delegate_) + UpdateDragStateInsideFolder(pointer, point); + // EndDrag was called before if |drag_view_| is NULL. if (!drag_view_) return; @@ -591,13 +606,15 @@ void AppsGridView::EndDrag(bool cancel) { drag_and_drop_host_->EndDrag(cancel); if (IsDraggingForReparentInHiddenGridView()) folder_delegate_->DispatchEndDragEventForReparent(true); - } else if (!cancel && dragging()) { + } else { if (IsDraggingForReparentInHiddenGridView()) { // Forward the EndDrag event to the root level grid view. - folder_delegate_->DispatchEndDragEventForReparent(false); + folder_delegate_->DispatchEndDragEventForReparent(cancel); EndDragForReparentInHiddenFolderGridView(); return; - } else { + } + + if (!cancel && dragging()) { // Regular drag ending path, ie, not for reparenting. CalculateDropTarget(last_drag_point_, true); if (IsValidIndex(drop_target_)) { @@ -728,15 +745,12 @@ void AppsGridView::InitiateDragFromReparentItemInRootLevelGridView( dragging_for_reparent_item_ = true; } -void AppsGridView::UpdateDragFromReparentItem( - Pointer pointer, - const ui::LocatedEvent& event) { +void AppsGridView::UpdateDragFromReparentItem(Pointer pointer, + const gfx::Point& drag_point) { DCHECK(drag_view_); DCHECK(IsDraggingForReparentInRootLevelGridView()); - gfx::Point drag_point_in_grid_view; - ExtractDragLocation(event, &drag_point_in_grid_view); - UpdateDrag(pointer, drag_point_in_grid_view); + UpdateDrag(pointer, drag_point); } bool AppsGridView::IsDraggedView(const views::View* view) const { @@ -1290,16 +1304,15 @@ void AppsGridView::OnFolderDroppingTimer() { SetAsFolderDroppingTarget(drop_target_, true); } -void AppsGridView::UpdateDragStateInsideFolder( - Pointer pointer, - const ui::LocatedEvent& event) { +void AppsGridView::UpdateDragStateInsideFolder(Pointer pointer, + const gfx::Point& drag_point) { if (IsUnderOEMFolder()) return; if (IsDraggingForReparentInHiddenGridView()) { // Dispatch drag event to root level grid view for re-parenting folder // folder item purpose. - DispatchDragEventForReparent(pointer, event); + DispatchDragEventForReparent(pointer, drag_point); return; } @@ -1353,10 +1366,9 @@ bool AppsGridView::IsUnderOEMFolder() { return folder_delegate_->IsOEMFolder(); } -void AppsGridView::DispatchDragEventForReparent( - Pointer pointer, - const ui::LocatedEvent& event) { - folder_delegate_->DispatchDragEventForReparent(pointer, event); +void AppsGridView::DispatchDragEventForReparent(Pointer pointer, + const gfx::Point& drag_point) { + folder_delegate_->DispatchDragEventForReparent(pointer, drag_point); } void AppsGridView::EndDragFromReparentItemInRootLevel( diff --git a/ui/app_list/views/apps_grid_view.h b/ui/app_list/views/apps_grid_view.h index 22d8bb19ed..2037444180 100644 --- a/ui/app_list/views/apps_grid_view.h +++ b/ui/app_list/views/apps_grid_view.h @@ -83,6 +83,9 @@ class APP_LIST_EXPORT AppsGridView : public views::View, int cols() { return cols_; } int rows_per_page() { return rows_per_page_; } + // This resets the grid view to a fresh state for showing the app list. + void ResetForShowApps(); + // Sets |model| to use. Note this does not take ownership of |model|. void SetModel(AppListModel* model); @@ -165,11 +168,11 @@ class APP_LIST_EXPORT AppsGridView : public views::View, // Updates drag in the root level grid view when receiving the drag event // dispatched from the hidden grid view for reparenting a folder item. void UpdateDragFromReparentItem(Pointer pointer, - const ui::LocatedEvent& event); + const gfx::Point& drag_point); // Dispatches the drag event from hidden grid view to the top level grid view. void DispatchDragEventForReparent(Pointer pointer, - const ui::LocatedEvent& event); + const gfx::Point& drag_point); // Handles EndDrag event dispatched from the hidden folder grid view in the // root level grid view to end reparenting a folder item. @@ -422,7 +425,7 @@ class APP_LIST_EXPORT AppsGridView : public views::View, // Updates drag state for dragging inside a folder's grid view. void UpdateDragStateInsideFolder(Pointer pointer, - const ui::LocatedEvent& event); + const gfx::Point& drag_point); // Returns true if drag event is happening in the root level AppsGridView // for reparenting a folder item. diff --git a/ui/app_list/views/apps_grid_view_folder_delegate.h b/ui/app_list/views/apps_grid_view_folder_delegate.h index 60d8f5e59d..a5f1d7d36e 100644 --- a/ui/app_list/views/apps_grid_view_folder_delegate.h +++ b/ui/app_list/views/apps_grid_view_folder_delegate.h @@ -36,8 +36,9 @@ class APP_LIST_EXPORT AppsGridViewFolderDelegate { // Dispatches drag event from the hidden grid view to the root level grid view // for re-parenting a folder item. - virtual void DispatchDragEventForReparent(AppsGridView::Pointer pointer, - const ui::LocatedEvent& event) = 0; + virtual void DispatchDragEventForReparent( + AppsGridView::Pointer pointer, + const gfx::Point& drag_point_in_folder_grid) = 0; // Dispatches EndDrag event from the hidden grid view to the root level grid // view for reparenting a folder item. diff --git a/ui/app_list/views/apps_grid_view_unittest.cc b/ui/app_list/views/apps_grid_view_unittest.cc index 313015a480..5e522e3433 100644 --- a/ui/app_list/views/apps_grid_view_unittest.cc +++ b/ui/app_list/views/apps_grid_view_unittest.cc @@ -195,9 +195,9 @@ class TestAppsGridViewFolderDelegate : public AppsGridViewFolderDelegate { const gfx::Point& drag_point_in_folder_grid) OVERRIDE {} - virtual void DispatchDragEventForReparent(AppsGridView::Pointer pointer, - const ui::LocatedEvent& event) - OVERRIDE {} + virtual void DispatchDragEventForReparent( + AppsGridView::Pointer pointer, + const gfx::Point& drag_point_in_folder_grid) OVERRIDE {} virtual void DispatchEndDragEventForReparent( bool events_forwarded_to_drag_drop_host) OVERRIDE {} diff --git a/ui/gfx/gpu_memory_buffer.h b/ui/gfx/gpu_memory_buffer.h index 2ddc89c3fb..94f54423c1 100644 --- a/ui/gfx/gpu_memory_buffer.h +++ b/ui/gfx/gpu_memory_buffer.h @@ -18,33 +18,44 @@ namespace gfx { enum GpuMemoryBufferType { EMPTY_BUFFER, SHARED_MEMORY_BUFFER, - ANDROID_NATIVE_BUFFER, IO_SURFACE_BUFFER, - GPU_MEMORY_BUFFER_TYPE_LAST = IO_SURFACE_BUFFER + ANDROID_NATIVE_BUFFER, + SURFACE_TEXTURE_BUFFER, + GPU_MEMORY_BUFFER_TYPE_LAST = SURFACE_TEXTURE_BUFFER +}; + +#if defined(OS_ANDROID) +struct SurfaceTextureId { + SurfaceTextureId() : primary_id(0), secondary_id(0) {} + SurfaceTextureId(int32 primary_id, int32 secondary_id) + : primary_id(primary_id), secondary_id(secondary_id) {} + int32 primary_id; + int32 secondary_id; }; +#endif struct GpuMemoryBufferHandle { GpuMemoryBufferHandle() : type(EMPTY_BUFFER), handle(base::SharedMemory::NULLHandle()) -#if defined(OS_ANDROID) - , native_buffer(NULL) -#endif #if defined(OS_MACOSX) , io_surface_id(0) #endif +#if defined(OS_ANDROID) + , native_buffer(NULL) +#endif { } bool is_null() const { return type == EMPTY_BUFFER; } GpuMemoryBufferType type; base::SharedMemoryHandle handle; -#if defined(OS_ANDROID) - EGLClientBuffer native_buffer; -#endif #if defined(OS_MACOSX) uint32 io_surface_id; #endif - +#if defined(OS_ANDROID) + EGLClientBuffer native_buffer; + SurfaceTextureId surface_texture_id; +#endif }; // Interface for creating and accessing a zero-copy GPU memory buffer. diff --git a/ui/gfx/native_widget_types.h b/ui/gfx/native_widget_types.h index 44fee5b760..2c3e1968a4 100644 --- a/ui/gfx/native_widget_types.h +++ b/ui/gfx/native_widget_types.h @@ -122,12 +122,6 @@ typedef aura::Window* NativeView; typedef aura::Window* NativeWindow; typedef SkRegion* NativeRegion; typedef ui::Event* NativeEvent; -#elif defined(OS_WIN) -typedef HCURSOR NativeCursor; -typedef HWND NativeView; -typedef HWND NativeWindow; -typedef HRGN NativeRegion; -typedef MSG NativeEvent; #elif defined(OS_IOS) typedef void* NativeCursor; typedef UIView* NativeView; @@ -208,30 +202,6 @@ typedef NativeImageType* NativeImage; // See comment at the top of the file for usage. typedef intptr_t NativeViewId; -#if defined(OS_WIN) && !defined(USE_AURA) -// Convert a NativeViewId to a NativeView. -// -// On Windows, we pass an HWND into the renderer. As stated above, the renderer -// should not be performing operations on the view. -static inline NativeView NativeViewFromId(NativeViewId id) { - return reinterpret_cast<NativeView>(id); -} -#define NativeViewFromIdInBrowser(x) NativeViewFromId(x) -#elif defined(OS_POSIX) || defined(USE_AURA) -// On Mac, Linux and USE_AURA, a NativeView is a pointer to an object, and is -// useless outside the process in which it was created. NativeViewFromId should -// only be used inside the appropriate platform ifdef outside of the browser. -// (NativeViewFromIdInBrowser can be used everywhere in the browser.) If your -// cross-platform design involves a call to NativeViewFromId from outside the -// browser it will never work on Mac or Linux and is fundamentally broken. - -// Please do not call this from outside the browser. It won't work; the name -// should give you a subtle hint. -static inline NativeView NativeViewFromIdInBrowser(NativeViewId id) { - return reinterpret_cast<NativeView>(id); -} -#endif // defined(OS_POSIX) - // PluginWindowHandle is an abstraction wrapping "the types of windows // used by NPAPI plugins". On Windows it's an HWND, on X it's an X // window id. diff --git a/ui/gl/android/surface_texture_tracker.cc b/ui/gl/android/surface_texture_tracker.cc new file mode 100644 index 0000000000..d0ff16add9 --- /dev/null +++ b/ui/gl/android/surface_texture_tracker.cc @@ -0,0 +1,26 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ui/gl/android/surface_texture_tracker.h" + +#include "base/logging.h" + +namespace gfx { +namespace { +SurfaceTextureTracker* g_instance = NULL; +} // namespace + +// static +SurfaceTextureTracker* SurfaceTextureTracker::GetInstance() { + DCHECK(g_instance); + return g_instance; +} + +// static +void SurfaceTextureTracker::InitInstance(SurfaceTextureTracker* tracker) { + DCHECK(!g_instance); + g_instance = tracker; +} + +} // namespace gfx diff --git a/ui/gl/android/surface_texture_tracker.h b/ui/gl/android/surface_texture_tracker.h new file mode 100644 index 0000000000..a86f144c27 --- /dev/null +++ b/ui/gl/android/surface_texture_tracker.h @@ -0,0 +1,32 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef UI_GL_ANDROID_SURFACE_TEXTURE_TRACKER_H_ +#define UI_GL_ANDROID_SURFACE_TEXTURE_TRACKER_H_ + +#include "base/memory/ref_counted.h" +#include "ui/gl/gl_export.h" + +namespace gfx { + +class SurfaceTexture; + +// This interface is used to take ownership of preallocated surface textures +// with specific ids. +class GL_EXPORT SurfaceTextureTracker { + public: + static SurfaceTextureTracker* GetInstance(); + static void InitInstance(SurfaceTextureTracker* tracker); + + virtual scoped_refptr<SurfaceTexture> AcquireSurfaceTexture( + int primary_id, + int secondary_id) = 0; + + protected: + virtual ~SurfaceTextureTracker() {} +}; + +} // namespace gfx + +#endif // UI_GL_ANDROID_SURFACE_TEXTURE_TRACKER_H_ diff --git a/ui/gl/gl.gyp b/ui/gl/gl.gyp index a45e8ce2ca..dec3585e8e 100644 --- a/ui/gl/gl.gyp +++ b/ui/gl/gl.gyp @@ -50,6 +50,8 @@ 'android/surface_texture.h', 'android/surface_texture_listener.cc', 'android/surface_texture_listener.h', + 'android/surface_texture_tracker.cc', + 'android/surface_texture_tracker.h', 'gl_bindings.h', 'gl_bindings_skia_in_process.cc', 'gl_bindings_skia_in_process.h', @@ -279,6 +281,8 @@ 'sources': [ 'gl_image_android_native_buffer.cc', 'gl_image_android_native_buffer.h', + 'gl_image_surface_texture.cc', + 'gl_image_surface_texture.h', ], 'link_settings': { 'libraries': [ diff --git a/ui/gl/gl.target.darwin-arm.mk b/ui/gl/gl.target.darwin-arm.mk index 71f86db671..934c5ec6a4 100644 --- a/ui/gl/gl.target.darwin-arm.mk +++ b/ui/gl/gl.target.darwin-arm.mk @@ -87,6 +87,7 @@ LOCAL_SRC_FILES := \ ui/gl/android/scoped_java_surface.cc \ ui/gl/android/surface_texture.cc \ ui/gl/android/surface_texture_listener.cc \ + ui/gl/android/surface_texture_tracker.cc \ ui/gl/gl_bindings_skia_in_process.cc \ ui/gl/gl_context.cc \ ui/gl/gl_context_android.cc \ @@ -120,7 +121,8 @@ LOCAL_SRC_FILES := \ ui/gl/gl_surface_egl.cc \ ui/gl/gl_egl_api_implementation.cc \ ui/gl/gl_implementation_osmesa.cc \ - ui/gl/gl_image_android_native_buffer.cc + ui/gl/gl_image_android_native_buffer.cc \ + ui/gl/gl_image_surface_texture.cc # Flags passed to both C and C++ files. diff --git a/ui/gl/gl.target.darwin-mips.mk b/ui/gl/gl.target.darwin-mips.mk index 8d4cf620f1..f2ed0d88e0 100644 --- a/ui/gl/gl.target.darwin-mips.mk +++ b/ui/gl/gl.target.darwin-mips.mk @@ -87,6 +87,7 @@ LOCAL_SRC_FILES := \ ui/gl/android/scoped_java_surface.cc \ ui/gl/android/surface_texture.cc \ ui/gl/android/surface_texture_listener.cc \ + ui/gl/android/surface_texture_tracker.cc \ ui/gl/gl_bindings_skia_in_process.cc \ ui/gl/gl_context.cc \ ui/gl/gl_context_android.cc \ @@ -120,7 +121,8 @@ LOCAL_SRC_FILES := \ ui/gl/gl_surface_egl.cc \ ui/gl/gl_egl_api_implementation.cc \ ui/gl/gl_implementation_osmesa.cc \ - ui/gl/gl_image_android_native_buffer.cc + ui/gl/gl_image_android_native_buffer.cc \ + ui/gl/gl_image_surface_texture.cc # Flags passed to both C and C++ files. diff --git a/ui/gl/gl.target.darwin-x86.mk b/ui/gl/gl.target.darwin-x86.mk index 8db82e80b6..fced35ffcf 100644 --- a/ui/gl/gl.target.darwin-x86.mk +++ b/ui/gl/gl.target.darwin-x86.mk @@ -87,6 +87,7 @@ LOCAL_SRC_FILES := \ ui/gl/android/scoped_java_surface.cc \ ui/gl/android/surface_texture.cc \ ui/gl/android/surface_texture_listener.cc \ + ui/gl/android/surface_texture_tracker.cc \ ui/gl/gl_bindings_skia_in_process.cc \ ui/gl/gl_context.cc \ ui/gl/gl_context_android.cc \ @@ -120,7 +121,8 @@ LOCAL_SRC_FILES := \ ui/gl/gl_surface_egl.cc \ ui/gl/gl_egl_api_implementation.cc \ ui/gl/gl_implementation_osmesa.cc \ - ui/gl/gl_image_android_native_buffer.cc + ui/gl/gl_image_android_native_buffer.cc \ + ui/gl/gl_image_surface_texture.cc # Flags passed to both C and C++ files. diff --git a/ui/gl/gl.target.darwin-x86_64.mk b/ui/gl/gl.target.darwin-x86_64.mk index e55094c6a6..14b53990a7 100644 --- a/ui/gl/gl.target.darwin-x86_64.mk +++ b/ui/gl/gl.target.darwin-x86_64.mk @@ -87,6 +87,7 @@ LOCAL_SRC_FILES := \ ui/gl/android/scoped_java_surface.cc \ ui/gl/android/surface_texture.cc \ ui/gl/android/surface_texture_listener.cc \ + ui/gl/android/surface_texture_tracker.cc \ ui/gl/gl_bindings_skia_in_process.cc \ ui/gl/gl_context.cc \ ui/gl/gl_context_android.cc \ @@ -120,7 +121,8 @@ LOCAL_SRC_FILES := \ ui/gl/gl_surface_egl.cc \ ui/gl/gl_egl_api_implementation.cc \ ui/gl/gl_implementation_osmesa.cc \ - ui/gl/gl_image_android_native_buffer.cc + ui/gl/gl_image_android_native_buffer.cc \ + ui/gl/gl_image_surface_texture.cc # Flags passed to both C and C++ files. diff --git a/ui/gl/gl.target.linux-arm.mk b/ui/gl/gl.target.linux-arm.mk index 71f86db671..934c5ec6a4 100644 --- a/ui/gl/gl.target.linux-arm.mk +++ b/ui/gl/gl.target.linux-arm.mk @@ -87,6 +87,7 @@ LOCAL_SRC_FILES := \ ui/gl/android/scoped_java_surface.cc \ ui/gl/android/surface_texture.cc \ ui/gl/android/surface_texture_listener.cc \ + ui/gl/android/surface_texture_tracker.cc \ ui/gl/gl_bindings_skia_in_process.cc \ ui/gl/gl_context.cc \ ui/gl/gl_context_android.cc \ @@ -120,7 +121,8 @@ LOCAL_SRC_FILES := \ ui/gl/gl_surface_egl.cc \ ui/gl/gl_egl_api_implementation.cc \ ui/gl/gl_implementation_osmesa.cc \ - ui/gl/gl_image_android_native_buffer.cc + ui/gl/gl_image_android_native_buffer.cc \ + ui/gl/gl_image_surface_texture.cc # Flags passed to both C and C++ files. diff --git a/ui/gl/gl.target.linux-mips.mk b/ui/gl/gl.target.linux-mips.mk index 8d4cf620f1..f2ed0d88e0 100644 --- a/ui/gl/gl.target.linux-mips.mk +++ b/ui/gl/gl.target.linux-mips.mk @@ -87,6 +87,7 @@ LOCAL_SRC_FILES := \ ui/gl/android/scoped_java_surface.cc \ ui/gl/android/surface_texture.cc \ ui/gl/android/surface_texture_listener.cc \ + ui/gl/android/surface_texture_tracker.cc \ ui/gl/gl_bindings_skia_in_process.cc \ ui/gl/gl_context.cc \ ui/gl/gl_context_android.cc \ @@ -120,7 +121,8 @@ LOCAL_SRC_FILES := \ ui/gl/gl_surface_egl.cc \ ui/gl/gl_egl_api_implementation.cc \ ui/gl/gl_implementation_osmesa.cc \ - ui/gl/gl_image_android_native_buffer.cc + ui/gl/gl_image_android_native_buffer.cc \ + ui/gl/gl_image_surface_texture.cc # Flags passed to both C and C++ files. diff --git a/ui/gl/gl.target.linux-x86.mk b/ui/gl/gl.target.linux-x86.mk index 8db82e80b6..fced35ffcf 100644 --- a/ui/gl/gl.target.linux-x86.mk +++ b/ui/gl/gl.target.linux-x86.mk @@ -87,6 +87,7 @@ LOCAL_SRC_FILES := \ ui/gl/android/scoped_java_surface.cc \ ui/gl/android/surface_texture.cc \ ui/gl/android/surface_texture_listener.cc \ + ui/gl/android/surface_texture_tracker.cc \ ui/gl/gl_bindings_skia_in_process.cc \ ui/gl/gl_context.cc \ ui/gl/gl_context_android.cc \ @@ -120,7 +121,8 @@ LOCAL_SRC_FILES := \ ui/gl/gl_surface_egl.cc \ ui/gl/gl_egl_api_implementation.cc \ ui/gl/gl_implementation_osmesa.cc \ - ui/gl/gl_image_android_native_buffer.cc + ui/gl/gl_image_android_native_buffer.cc \ + ui/gl/gl_image_surface_texture.cc # Flags passed to both C and C++ files. diff --git a/ui/gl/gl.target.linux-x86_64.mk b/ui/gl/gl.target.linux-x86_64.mk index e55094c6a6..14b53990a7 100644 --- a/ui/gl/gl.target.linux-x86_64.mk +++ b/ui/gl/gl.target.linux-x86_64.mk @@ -87,6 +87,7 @@ LOCAL_SRC_FILES := \ ui/gl/android/scoped_java_surface.cc \ ui/gl/android/surface_texture.cc \ ui/gl/android/surface_texture_listener.cc \ + ui/gl/android/surface_texture_tracker.cc \ ui/gl/gl_bindings_skia_in_process.cc \ ui/gl/gl_context.cc \ ui/gl/gl_context_android.cc \ @@ -120,7 +121,8 @@ LOCAL_SRC_FILES := \ ui/gl/gl_surface_egl.cc \ ui/gl/gl_egl_api_implementation.cc \ ui/gl/gl_implementation_osmesa.cc \ - ui/gl/gl_image_android_native_buffer.cc + ui/gl/gl_image_android_native_buffer.cc \ + ui/gl/gl_image_surface_texture.cc # Flags passed to both C and C++ files. diff --git a/ui/gl/gl_image_android.cc b/ui/gl/gl_image_android.cc index 4d04be1a4c..a619c85017 100644 --- a/ui/gl/gl_image_android.cc +++ b/ui/gl/gl_image_android.cc @@ -8,6 +8,7 @@ #include "ui/gl/gl_image_android_native_buffer.h" #include "ui/gl/gl_image_shm.h" #include "ui/gl/gl_image_stub.h" +#include "ui/gl/gl_image_surface_texture.h" #include "ui/gl/gl_implementation.h" namespace gfx { @@ -49,6 +50,14 @@ scoped_refptr<GLImage> GLImage::CreateGLImageForGpuMemoryBuffer( return image; } + case SURFACE_TEXTURE_BUFFER: { + scoped_refptr<GLImageSurfaceTexture> image( + new GLImageSurfaceTexture(size)); + if (!image->Initialize(buffer)) + return NULL; + + return image; + } default: NOTREACHED(); return NULL; diff --git a/ui/gl/gl_image_surface_texture.cc b/ui/gl/gl_image_surface_texture.cc new file mode 100644 index 0000000000..8d0a0e7e22 --- /dev/null +++ b/ui/gl/gl_image_surface_texture.cc @@ -0,0 +1,75 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ui/gl/gl_image_surface_texture.h" + +#include "base/debug/trace_event.h" +#include "ui/gl/android/surface_texture.h" +#include "ui/gl/android/surface_texture_tracker.h" + +namespace gfx { + +GLImageSurfaceTexture::GLImageSurfaceTexture(gfx::Size size) + : size_(size), texture_id_(0) {} + +GLImageSurfaceTexture::~GLImageSurfaceTexture() { Destroy(); } + +bool GLImageSurfaceTexture::Initialize(gfx::GpuMemoryBufferHandle buffer) { + DCHECK(!surface_texture_); + surface_texture_ = + SurfaceTextureTracker::GetInstance()->AcquireSurfaceTexture( + buffer.surface_texture_id.primary_id, + buffer.surface_texture_id.secondary_id); + return !!surface_texture_; +} + +void GLImageSurfaceTexture::Destroy() { + surface_texture_ = NULL; + texture_id_ = 0; +} + +gfx::Size GLImageSurfaceTexture::GetSize() { return size_; } + +bool GLImageSurfaceTexture::BindTexImage(unsigned target) { + TRACE_EVENT0("gpu", "GLImageSurfaceTexture::BindTexImage"); + + if (target != GL_TEXTURE_EXTERNAL_OES) { + LOG(ERROR) + << "Surface texture can only be bound to TEXTURE_EXTERNAL_OES target"; + return false; + } + + GLint texture_id; + glGetIntegerv(GL_TEXTURE_BINDING_EXTERNAL_OES, &texture_id); + DCHECK(texture_id); + + if (texture_id_ && texture_id_ != texture_id) { + LOG(ERROR) << "Surface texture can only be bound to one texture ID"; + return false; + } + + DCHECK(surface_texture_); + if (texture_id != texture_id_) { + // Note: Surface textures used as gpu memory buffers are created with an + // initial dummy texture id of 0. We need to call DetachFromGLContext() here + // to detach from the dummy texture before we can attach to a real texture + // id. DetachFromGLContext() will delete the texture for the current + // attachment point so it's important that this is never called when + // attached to a real texture id. Detaching from the dummy texture id should + // not cause any problems as the GL should silently ignore 0 when passed to + // glDeleteTextures. + DCHECK_EQ(0, texture_id_); + surface_texture_->DetachFromGLContext(); + + // This will attach the surface texture to the texture currently bound to + // GL_TEXTURE_EXTERNAL_OES target. + surface_texture_->AttachToGLContext(); + texture_id_ = texture_id; + } + + surface_texture_->UpdateTexImage(); + return true; +} + +} // namespace gfx diff --git a/ui/gl/gl_image_surface_texture.h b/ui/gl/gl_image_surface_texture.h new file mode 100644 index 0000000000..0b771a37f8 --- /dev/null +++ b/ui/gl/gl_image_surface_texture.h @@ -0,0 +1,45 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef UI_GL_GL_IMAGE_SURFACE_TEXTURE_H_ +#define UI_GL_GL_IMAGE_SURFACE_TEXTURE_H_ + +#include "base/memory/ref_counted.h" +#include "ui/gl/gl_bindings.h" +#include "ui/gl/gl_image.h" + +namespace gfx { + +class SurfaceTexture; + +class GL_EXPORT GLImageSurfaceTexture : public GLImage { + public: + explicit GLImageSurfaceTexture(gfx::Size size); + + bool Initialize(gfx::GpuMemoryBufferHandle buffer); + + // Overridden from GLImage: + virtual void Destroy() OVERRIDE; + virtual gfx::Size GetSize() OVERRIDE; + virtual bool BindTexImage(unsigned target) OVERRIDE; + virtual void ReleaseTexImage(unsigned target) OVERRIDE {} + virtual void WillUseTexImage() OVERRIDE {} + virtual void DidUseTexImage() OVERRIDE {} + virtual void WillModifyTexImage() OVERRIDE {} + virtual void DidModifyTexImage() OVERRIDE {} + + protected: + virtual ~GLImageSurfaceTexture(); + + private: + scoped_refptr<SurfaceTexture> surface_texture_; + gfx::Size size_; + GLint texture_id_; + + DISALLOW_COPY_AND_ASSIGN(GLImageSurfaceTexture); +}; + +} // namespace gfx + +#endif // UI_GL_GL_IMAGE_SURFACE_TEXTURE_H_ diff --git a/ui/keyboard/resources/elements/kb-key.html b/ui/keyboard/resources/elements/kb-key.html index e430edcc5f..6b9103af73 100644 --- a/ui/keyboard/resources/elements/kb-key.html +++ b/ui/keyboard/resources/elements/kb-key.html @@ -29,6 +29,7 @@ margin: auto; position: absolute; right: 0; + text-align: center; top: 0; } diff --git a/ui/keyboard/resources/elements/kb-shift-key.html b/ui/keyboard/resources/elements/kb-shift-key.html index 1deb07dce0..4deab642e1 100644 --- a/ui/keyboard/resources/elements/kb-shift-key.html +++ b/ui/keyboard/resources/elements/kb-shift-key.html @@ -9,64 +9,31 @@ extends="kb-key"> <template> <style> - :host() { - border-radius: 2px; - border-style: solid; - border-width: 1px 0; - color: #ffffff; - font-family: roboto-bold; - font-weight: 300; - } + .shift-light-wrapper { + bottom: 3px; + height: 10%; + margin: 0; + padding: 0; + position: absolute; + width: 100%; + } - :host(.active) { - -webkit-box-shadow: inset 0 1px #969696, inset 0 -1px #6f6f6f; - background-image: -webkit-linear-gradient(#8b8b8b, #7d7d7d); - background-size: cover; - border-bottom-color: #5b5b5b; - border-top-color: #a4a4a4; - } - - :host() .key { - background-image: none; - background-position: center; - background-repeat: no-repeat; - background-size: contain; - bottom: 0; - font-size: 70%; - height: 70%; - left: 0; - margin: auto; - position: absolute; - right: 0; - top: 0; - width: auto; - } - - :host() .shift-light-wrapper { - bottom: 3px; - height: 10%; - margin: 0; - padding: 0; - position: absolute; - width: 100%; - } - - :host() .shift-light { - -webkit-box-shadow: inset 0 1px #101010, inset 0 -1px #444444; - background-image: -webkit-linear-gradient(#101010, #000000); - border: solid; - border-bottom-color: #1d1d1d; - border-top-color: #2d2d2d; - border-width: 1px 0; - height: 0.3em; - margin: 0 auto; - position: relative; - width: 1.8em; - } - </style> - <div id="key" class="key"> </div> + .shift-light { + -webkit-box-shadow: inset 0 1px #101010, inset 0 -1px #444444; + background-image: -webkit-linear-gradient(#101010, #000000); + border: solid; + border-bottom-color: #1d1d1d; + border-top-color: #2d2d2d; + border-width: 1px 0; + height: 0.3em; + margin: 0 auto; + position: relative; + width: 1.8em; + } + </style> <div class="shift-light-wrapper"> <div class="shift-light"> </div> </div> + <shadow></shadow> </template> </polymer-element> diff --git a/ui/keyboard/resources/main.css b/ui/keyboard/resources/main.css index 2c5b621eb3..99c2c27080 100644 --- a/ui/keyboard/resources/main.css +++ b/ui/keyboard/resources/main.css @@ -18,18 +18,18 @@ kb-keyboard.alt-active kb-modifier-key[char=Alt] { color: lightblue; } -kb-keyboard[keyset="upper"] kb-shift-key.dark /shadow-deep/ .key { +kb-keyboard[keyset="upper"] kb-shift-key.dark /deep/ .key { background-image: url('images/shift-filled.svg'); } -kb-keyboard[keyset="lower"] kb-shift-key /shadow-deep/ .key { +kb-keyboard[keyset="lower"] kb-shift-key /deep/ .key{ background-image: url('images/shift.svg'); } /** * Controls whether the shift key should be highlighted or not. */ -kb-keyboard.caps-locked kb-shift-key.dark /shadow-deep/ +kb-keyboard.caps-locked kb-shift-key.dark /deep/ .shift-light { -webkit-box-shadow: 0 1px 1px rgba(213, 213, 213, 0.5), 0 -1px 1px rgba(213, 213, 213, 0.5); @@ -37,7 +37,7 @@ kb-keyboard.caps-locked kb-shift-key.dark /shadow-deep/ border: none; height: 0.2em; } -kb-keyboard.caps-locked kb-shift-key.dark /shadow-deep/ +kb-keyboard.caps-locked kb-shift-key.dark /deep/ .shift-light-wrapper { bottom: 2px; } @@ -72,15 +72,15 @@ kb-row:nth-child(n+3) kb-key:not(.dark):not(.active){ border-top-color: #717171; } -kb-row:nth-child(2) kb-key:not([invert]) /shadow-deep/ .hint { +kb-row:nth-child(2) kb-key:not([invert]) /deep/ .hint { color: #2C2C2C; } -kb-row:nth-child(3) kb-key:not([invert]) /shadow-deep/ .hint { +kb-row:nth-child(3) kb-key:not([invert]) /deep/ .hint { color: #272727; } -kb-row:nth-child(n+3) kb-key:not([invert]) /shadow-deep/ .hint { +kb-row:nth-child(n+3) kb-key:not([invert]) /deep/ .hint { color: #232323; } diff --git a/ui/views/controls/menu/menu_controller.cc b/ui/views/controls/menu/menu_controller.cc index 5d58c697e7..ea854a2e24 100644 --- a/ui/views/controls/menu/menu_controller.cc +++ b/ui/views/controls/menu/menu_controller.cc @@ -21,8 +21,6 @@ #include "ui/base/l10n/l10n_util.h" #include "ui/events/event_constants.h" #include "ui/events/event_utils.h" -#include "ui/events/keycodes/keyboard_code_conversion.h" -#include "ui/events/keycodes/keyboard_codes.h" #include "ui/gfx/canvas.h" #include "ui/gfx/native_widget_types.h" #include "ui/gfx/screen.h" @@ -32,6 +30,7 @@ #include "ui/views/controls/menu/menu_config.h" #include "ui/views/controls/menu/menu_controller_delegate.h" #include "ui/views/controls/menu/menu_host_root_view.h" +#include "ui/views/controls/menu/menu_message_pump_dispatcher.h" #include "ui/views/controls/menu/menu_scroll_view_container.h" #include "ui/views/controls/menu/submenu_view.h" #include "ui/views/drag_utils.h" @@ -43,17 +42,16 @@ #include "ui/views/widget/root_view.h" #include "ui/views/widget/tooltip_manager.h" #include "ui/views/widget/widget.h" +#include "ui/wm/public/activation_change_observer.h" +#include "ui/wm/public/activation_client.h" #include "ui/wm/public/dispatcher_client.h" +#include "ui/wm/public/drag_drop_client.h" #if defined(OS_WIN) #include "ui/base/win/internal_constants.h" #include "ui/views/win/hwnd_util.h" #endif -#if defined(USE_X11) -#include <X11/Xlib.h> -#endif - using base::Time; using base::TimeDelta; using ui::OSExchangeData; @@ -101,6 +99,67 @@ bool TitleMatchesMnemonic(MenuItemView* menu, base::char16 key) { return !lower_title.empty() && lower_title[0] == key; } +aura::Window* GetOwnerRootWindow(views::Widget* owner) { + return owner ? owner->GetNativeWindow()->GetRootWindow() : NULL; +} + +// ActivationChangeObserverImpl is used to observe activation changes and close +// the menu. Additionally it listens for the root window to be destroyed and +// cancel the menu as well. +class ActivationChangeObserverImpl + : public aura::client::ActivationChangeObserver, + public aura::WindowObserver, + public ui::EventHandler { + public: + ActivationChangeObserverImpl(MenuController* controller, aura::Window* root) + : controller_(controller), + root_(root) { + aura::client::GetActivationClient(root_)->AddObserver(this); + root_->AddObserver(this); + root_->AddPreTargetHandler(this); + } + + virtual ~ActivationChangeObserverImpl() { + Cleanup(); + } + + // aura::client::ActivationChangeObserver: + virtual void OnWindowActivated(aura::Window* gained_active, + aura::Window* lost_active) OVERRIDE { + if (!controller_->drag_in_progress()) + controller_->CancelAll(); + } + + // aura::WindowObserver: + virtual void OnWindowDestroying(aura::Window* window) OVERRIDE { + Cleanup(); + } + + // ui::EventHandler: + virtual void OnCancelMode(ui::CancelModeEvent* event) OVERRIDE { + controller_->CancelAll(); + } + + private: + void Cleanup() { + if (!root_) + return; + // The ActivationClient may have been destroyed by the time we get here. + aura::client::ActivationClient* client = + aura::client::GetActivationClient(root_); + if (client) + client->RemoveObserver(this); + root_->RemovePreTargetHandler(this); + root_->RemoveObserver(this); + root_ = NULL; + } + + MenuController* controller_; + aura::Window* root_; + + DISALLOW_COPY_AND_ASSIGN(ActivationChangeObserverImpl); +}; + } // namespace // Returns the first descendant of |view| that is hot tracked. @@ -1001,94 +1060,6 @@ void MenuController::StartDrag(SubmenuView* source, } // else case, someone canceled us, don't do anything } -#if defined(OS_WIN) -uint32_t MenuController::Dispatch(const MSG& msg) { - DCHECK(blocking_run_); - - if (exit_type_ == EXIT_ALL || exit_type_ == EXIT_DESTROYED) - return (POST_DISPATCH_QUIT_LOOP | POST_DISPATCH_PERFORM_DEFAULT); - - // NOTE: we don't get WM_ACTIVATE or anything else interesting in here. - switch (msg.message) { - case WM_CONTEXTMENU: { - MenuItemView* item = pending_state_.item; - if (item && item->GetRootMenuItem() != item) { - gfx::Point screen_loc(0, item->height()); - View::ConvertPointToScreen(item, &screen_loc); - ui::MenuSourceType source_type = ui::MENU_SOURCE_MOUSE; - if (GET_X_LPARAM(msg.lParam) == -1 && GET_Y_LPARAM(msg.lParam) == -1) - source_type = ui::MENU_SOURCE_KEYBOARD; - item->GetDelegate()->ShowContextMenu(item, item->GetCommand(), - screen_loc, source_type); - } - return POST_DISPATCH_NONE; - } - - // NOTE: focus wasn't changed when the menu was shown. As such, don't - // dispatch key events otherwise the focused window will get the events. - case WM_KEYDOWN: { - bool result = OnKeyDown(ui::KeyboardCodeFromNative(msg)); - TranslateMessage(&msg); - return result ? POST_DISPATCH_NONE : POST_DISPATCH_QUIT_LOOP; - } - case WM_CHAR: { - bool should_exit = SelectByChar(static_cast<base::char16>(msg.wParam)); - return should_exit ? POST_DISPATCH_QUIT_LOOP : POST_DISPATCH_NONE; - } - case WM_KEYUP: - return POST_DISPATCH_NONE; - - case WM_SYSKEYUP: - // We may have been shown on a system key, as such don't do anything - // here. If another system key is pushed we'll get a WM_SYSKEYDOWN and - // close the menu. - return POST_DISPATCH_NONE; - - case WM_CANCELMODE: - case WM_SYSKEYDOWN: - // Exit immediately on system keys. - Cancel(EXIT_ALL); - return POST_DISPATCH_QUIT_LOOP; - - default: - break; - } - return POST_DISPATCH_PERFORM_DEFAULT | - (exit_type_ == EXIT_NONE ? POST_DISPATCH_NONE - : POST_DISPATCH_QUIT_LOOP); -} -#else -uint32_t MenuController::Dispatch(const base::NativeEvent& event) { - if (exit_type_ == EXIT_ALL || exit_type_ == EXIT_DESTROYED) - return (POST_DISPATCH_QUIT_LOOP | POST_DISPATCH_PERFORM_DEFAULT); - - switch (ui::EventTypeFromNative(event)) { - case ui::ET_KEY_PRESSED: { - if (!OnKeyDown(ui::KeyboardCodeFromNative(event))) - return POST_DISPATCH_QUIT_LOOP; - - // Do not check mnemonics if the Alt or Ctrl modifiers are pressed. - int flags = ui::EventFlagsFromNative(event); - if ((flags & (ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN)) == 0) { - char c = ui::GetCharacterFromKeyCode( - ui::KeyboardCodeFromNative(event), flags); - if (SelectByChar(c)) - return POST_DISPATCH_QUIT_LOOP; - } - return POST_DISPATCH_NONE; - } - case ui::ET_KEY_RELEASED: - return POST_DISPATCH_NONE; - default: - break; - } - - return POST_DISPATCH_PERFORM_DEFAULT | - (exit_type_ == EXIT_NONE ? POST_DISPATCH_NONE - : POST_DISPATCH_QUIT_LOOP); -} -#endif - bool MenuController::OnKeyDown(ui::KeyboardCode key_code) { DCHECK(blocking_run_); @@ -1155,11 +1126,6 @@ bool MenuController::OnKeyDown(ui::KeyboardCode key_code) { CloseSubmenu(); break; -#if defined(OS_WIN) - case VK_APPS: - break; -#endif - default: break; } @@ -1205,6 +1171,25 @@ MenuController::~MenuController() { StopCancelAllTimer(); } +void MenuController::RunMessageLoop(bool nested_menu) { + internal::MenuMessagePumpDispatcher nested_dispatcher(this); + + // |owner_| may be NULL. + aura::Window* root = GetOwnerRootWindow(owner_); + if (root) { + scoped_ptr<ActivationChangeObserverImpl> observer; + if (!nested_menu) + observer.reset(new ActivationChangeObserverImpl(this, root)); + aura::client::GetDispatcherClient(root) + ->RunWithDispatcher(&nested_dispatcher); + } else { + base::MessageLoopForUI* loop = base::MessageLoopForUI::current(); + base::MessageLoop::ScopedNestableTaskAllower allow(loop); + base::RunLoop run_loop(&nested_dispatcher); + run_loop.Run(); + } +} + MenuController::SendAcceleratorResultType MenuController::SendAcceleratorToHotTrackedView() { CustomButton* hot_view = GetFirstHotTrackedView(pending_state_.item); @@ -2321,6 +2306,12 @@ void MenuController::SetExitType(ExitType type) { } } +bool MenuController::ShouldQuitNow() const { + aura::Window* root = GetOwnerRootWindow(owner_); + return !aura::client::GetDragDropClient(root) || + !aura::client::GetDragDropClient(root)->IsDragDropInProgress(); +} + void MenuController::HandleMouseLocation(SubmenuView* source, const gfx::Point& mouse_location) { if (showing_submenu_) @@ -2353,4 +2344,10 @@ void MenuController::HandleMouseLocation(SubmenuView* source, } } +gfx::Screen* MenuController::GetScreen() { + aura::Window* root = GetOwnerRootWindow(owner_); + return root ? gfx::Screen::GetScreenFor(root) + : gfx::Screen::GetNativeScreen(); +} + } // namespace views diff --git a/ui/views/controls/menu/menu_controller.h b/ui/views/controls/menu/menu_controller.h index 3425caf3a5..cab7baedaa 100644 --- a/ui/views/controls/menu/menu_controller.h +++ b/ui/views/controls/menu/menu_controller.h @@ -13,20 +13,22 @@ #include "base/compiler_specific.h" #include "base/memory/scoped_ptr.h" -#include "base/message_loop/message_pump_dispatcher.h" #include "base/timer/timer.h" #include "ui/events/event_constants.h" #include "ui/views/controls/menu/menu_delegate.h" #include "ui/views/controls/menu/menu_item_view.h" #include "ui/views/widget/widget_observer.h" -namespace ui { -class NativeTheme; -class OSExchangeData; +namespace base { +class MessagePumpDispatcher; } namespace gfx { class Screen; } +namespace ui { +class NativeTheme; +class OSExchangeData; +} namespace views { class MenuButton; @@ -37,6 +39,7 @@ class View; namespace internal { class MenuControllerDelegate; +class MenuMessagePumpDispatcher; class MenuRunnerImpl; } @@ -45,8 +48,7 @@ class MenuRunnerImpl; // MenuController is used internally by the various menu classes to manage // showing, selecting and drag/drop for menus. All relevant events are // forwarded to the MenuController from SubmenuView and MenuHost. -class VIEWS_EXPORT MenuController : public base::MessagePumpDispatcher, - public WidgetObserver { +class VIEWS_EXPORT MenuController : public WidgetObserver { public: // Enumeration of how the menu should exit. enum ExitType { @@ -140,6 +142,7 @@ class VIEWS_EXPORT MenuController : public base::MessagePumpDispatcher, static void TurnOffMenuSelectionHoldForTest(); private: + friend class internal::MenuMessagePumpDispatcher; friend class internal::MenuRunnerImpl; friend class MenuHostRootView; friend class MenuItemView; @@ -251,10 +254,6 @@ class VIEWS_EXPORT MenuController : public base::MessagePumpDispatcher, const ui::LocatedEvent& event); void StartDrag(SubmenuView* source, const gfx::Point& location); - // Dispatcher method. This returns true if the menu was canceled, or - // if the message is such that the menu should be closed. - virtual uint32_t Dispatch(const base::NativeEvent& event) OVERRIDE; - // Key processing. The return value of this is returned from Dispatch. // In other words, if this returns false (which happens if escape was // pressed, or a matching mnemonic was found) the message loop returns. diff --git a/ui/views/controls/menu/menu_controller_aura.cc b/ui/views/controls/menu/menu_controller_aura.cc deleted file mode 100644 index ec402c71df..0000000000 --- a/ui/views/controls/menu/menu_controller_aura.cc +++ /dev/null @@ -1,114 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "ui/views/controls/menu/menu_controller.h" - -#include "base/run_loop.h" -#include "ui/aura/window.h" -#include "ui/aura/window_observer.h" -#include "ui/gfx/screen.h" -#include "ui/views/widget/widget.h" -#include "ui/wm/public/activation_change_observer.h" -#include "ui/wm/public/activation_client.h" -#include "ui/wm/public/dispatcher_client.h" -#include "ui/wm/public/drag_drop_client.h" - -namespace views { - -namespace { - -// ActivationChangeObserverImpl is used to observe activation changes and close -// the menu. Additionally it listens for the root window to be destroyed and -// cancel the menu as well. -class ActivationChangeObserverImpl - : public aura::client::ActivationChangeObserver, - public aura::WindowObserver, - public ui::EventHandler { - public: - ActivationChangeObserverImpl(MenuController* controller, - aura::Window* root) - : controller_(controller), - root_(root) { - aura::client::GetActivationClient(root_)->AddObserver(this); - root_->AddObserver(this); - root_->AddPreTargetHandler(this); - } - - virtual ~ActivationChangeObserverImpl() { - Cleanup(); - } - - // aura::client::ActivationChangeObserver overrides: - virtual void OnWindowActivated(aura::Window* gained_active, - aura::Window* lost_active) OVERRIDE { - if (!controller_->drag_in_progress()) - controller_->CancelAll(); - } - - // aura::WindowObserver overrides: - virtual void OnWindowDestroying(aura::Window* window) OVERRIDE { - Cleanup(); - } - - // ui::EventHandler overrides: - virtual void OnCancelMode(ui::CancelModeEvent* event) OVERRIDE { - controller_->CancelAll(); - } - - private: - void Cleanup() { - if (!root_) - return; - // The ActivationClient may have been destroyed by the time we get here. - aura::client::ActivationClient* client = - aura::client::GetActivationClient(root_); - if (client) - client->RemoveObserver(this); - root_->RemovePreTargetHandler(this); - root_->RemoveObserver(this); - root_ = NULL; - } - - MenuController* controller_; - aura::Window* root_; - - DISALLOW_COPY_AND_ASSIGN(ActivationChangeObserverImpl); -}; - -aura::Window* GetOwnerRootWindow(views::Widget* owner) { - return owner ? owner->GetNativeWindow()->GetRootWindow() : NULL; -} - -} // namespace - -void MenuController::RunMessageLoop(bool nested_menu) { - // |owner_| may be NULL. - aura::Window* root = GetOwnerRootWindow(owner_); - if (root) { - scoped_ptr<ActivationChangeObserverImpl> observer; - if (!nested_menu) - observer.reset(new ActivationChangeObserverImpl(this, root)); - aura::client::GetDispatcherClient(root)->RunWithDispatcher(this); - } else { - base::MessageLoopForUI* loop = base::MessageLoopForUI::current(); - base::MessageLoop::ScopedNestableTaskAllower allow(loop); - base::RunLoop run_loop(this); - run_loop.Run(); - } -} - -bool MenuController::ShouldQuitNow() const { - aura::Window* root = GetOwnerRootWindow(owner_); - return !aura::client::GetDragDropClient(root) || - !aura::client::GetDragDropClient(root)->IsDragDropInProgress(); -} - -gfx::Screen* MenuController::GetScreen() { - aura::Window* root = GetOwnerRootWindow(owner_); - return root ? - gfx::Screen::GetScreenFor(root) : gfx::Screen::GetNativeScreen(); -} - - -} // namespace views diff --git a/ui/views/controls/menu/menu_message_pump_dispatcher.cc b/ui/views/controls/menu/menu_message_pump_dispatcher.cc new file mode 100644 index 0000000000..00d7930678 --- /dev/null +++ b/ui/views/controls/menu/menu_message_pump_dispatcher.cc @@ -0,0 +1,16 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ui/views/controls/menu/menu_message_pump_dispatcher.h" + +namespace views { +namespace internal { + +MenuMessagePumpDispatcher::MenuMessagePumpDispatcher(MenuController* controller) + : menu_controller_(controller) {} + +MenuMessagePumpDispatcher::~MenuMessagePumpDispatcher() {} + +} // namespace internal +} // namespace views diff --git a/ui/views/controls/menu/menu_message_pump_dispatcher.h b/ui/views/controls/menu/menu_message_pump_dispatcher.h new file mode 100644 index 0000000000..2f5696b7b3 --- /dev/null +++ b/ui/views/controls/menu/menu_message_pump_dispatcher.h @@ -0,0 +1,36 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef UI_VIEWS_CONTROLS_MENU_MENU_MESSAGE_PUMP_DISPATCHER_H_ +#define UI_VIEWS_CONTROLS_MENU_MENU_MESSAGE_PUMP_DISPATCHER_H_ + +#include "base/macros.h" +#include "base/message_loop/message_pump_dispatcher.h" + +namespace views { + +class MenuController; + +namespace internal { + +// A message-pump dispatcher object used to dispatch events from the nested +// message-loop initiated by the MenuController. +class MenuMessagePumpDispatcher : public base::MessagePumpDispatcher { + public: + explicit MenuMessagePumpDispatcher(MenuController* menu_controller); + virtual ~MenuMessagePumpDispatcher(); + + private: + // base::MessagePumpDispatcher: + virtual uint32_t Dispatch(const base::NativeEvent& event) OVERRIDE; + + MenuController* menu_controller_; + + DISALLOW_COPY_AND_ASSIGN(MenuMessagePumpDispatcher); +}; + +} // namespace internal +} // namespace views + +#endif // UI_VIEWS_CONTROLS_MENU_MENU_MESSAGE_PUMP_DISPATCHER_H_ diff --git a/ui/views/controls/menu/menu_message_pump_dispatcher_linux.cc b/ui/views/controls/menu/menu_message_pump_dispatcher_linux.cc new file mode 100644 index 0000000000..0172f8b33d --- /dev/null +++ b/ui/views/controls/menu/menu_message_pump_dispatcher_linux.cc @@ -0,0 +1,48 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ui/views/controls/menu/menu_message_pump_dispatcher.h" + +#include "ui/events/event_utils.h" +#include "ui/events/keycodes/keyboard_code_conversion.h" +#include "ui/events/keycodes/keyboard_codes.h" +#include "ui/views/controls/menu/menu_controller.h" + +namespace views { +namespace internal { + +uint32_t MenuMessagePumpDispatcher::Dispatch(const base::NativeEvent& event) { + if (menu_controller_->exit_type() == MenuController::EXIT_ALL || + menu_controller_->exit_type() == MenuController::EXIT_DESTROYED) + return (POST_DISPATCH_QUIT_LOOP | POST_DISPATCH_PERFORM_DEFAULT); + + switch (ui::EventTypeFromNative(event)) { + case ui::ET_KEY_PRESSED: { + if (!menu_controller_->OnKeyDown(ui::KeyboardCodeFromNative(event))) + return POST_DISPATCH_QUIT_LOOP; + + // Do not check mnemonics if the Alt or Ctrl modifiers are pressed. + int flags = ui::EventFlagsFromNative(event); + if ((flags & (ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN)) == 0) { + char c = ui::GetCharacterFromKeyCode(ui::KeyboardCodeFromNative(event), + flags); + if (menu_controller_->SelectByChar(c)) + return POST_DISPATCH_QUIT_LOOP; + } + return POST_DISPATCH_NONE; + } + case ui::ET_KEY_RELEASED: + return POST_DISPATCH_NONE; + default: + break; + } + + return POST_DISPATCH_PERFORM_DEFAULT | + (menu_controller_->exit_type() == MenuController::EXIT_NONE + ? POST_DISPATCH_NONE + : POST_DISPATCH_QUIT_LOOP); +} + +} // namespace internal +} // namespace views diff --git a/ui/views/controls/menu/menu_message_pump_dispatcher_win.cc b/ui/views/controls/menu/menu_message_pump_dispatcher_win.cc new file mode 100644 index 0000000000..f49b53618a --- /dev/null +++ b/ui/views/controls/menu/menu_message_pump_dispatcher_win.cc @@ -0,0 +1,78 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ui/views/controls/menu/menu_message_pump_dispatcher.h" + +#include <windowsx.h> + +#include "ui/events/event_utils.h" +#include "ui/events/keycodes/keyboard_code_conversion.h" +#include "ui/events/keycodes/keyboard_codes.h" +#include "ui/views/controls/menu/menu_controller.h" + +namespace views { +namespace internal { + +uint32_t MenuMessagePumpDispatcher::Dispatch(const MSG& msg) { + DCHECK(menu_controller_->IsBlockingRun()); + + if (menu_controller_->exit_type() == MenuController::EXIT_ALL || + menu_controller_->exit_type() == MenuController::EXIT_DESTROYED) + return (POST_DISPATCH_QUIT_LOOP | POST_DISPATCH_PERFORM_DEFAULT); + + // NOTE: we don't get WM_ACTIVATE or anything else interesting in here. + switch (msg.message) { + case WM_CONTEXTMENU: { + MenuItemView* item = menu_controller_->pending_state_.item; + if (item && item->GetRootMenuItem() != item) { + gfx::Point screen_loc(0, item->height()); + View::ConvertPointToScreen(item, &screen_loc); + ui::MenuSourceType source_type = ui::MENU_SOURCE_MOUSE; + if (GET_X_LPARAM(msg.lParam) == -1 && GET_Y_LPARAM(msg.lParam) == -1) + source_type = ui::MENU_SOURCE_KEYBOARD; + item->GetDelegate()->ShowContextMenu( + item, item->GetCommand(), screen_loc, source_type); + } + return POST_DISPATCH_NONE; + } + + // NOTE: focus wasn't changed when the menu was shown. As such, don't + // dispatch key events otherwise the focused window will get the events. + case WM_KEYDOWN: { + bool result = + menu_controller_->OnKeyDown(ui::KeyboardCodeFromNative(msg)); + TranslateMessage(&msg); + return result ? POST_DISPATCH_NONE : POST_DISPATCH_QUIT_LOOP; + } + case WM_CHAR: { + bool should_exit = + menu_controller_->SelectByChar(static_cast<base::char16>(msg.wParam)); + return should_exit ? POST_DISPATCH_QUIT_LOOP : POST_DISPATCH_NONE; + } + case WM_KEYUP: + return POST_DISPATCH_NONE; + + case WM_SYSKEYUP: + // We may have been shown on a system key, as such don't do anything + // here. If another system key is pushed we'll get a WM_SYSKEYDOWN and + // close the menu. + return POST_DISPATCH_NONE; + + case WM_CANCELMODE: + case WM_SYSKEYDOWN: + // Exit immediately on system keys. + menu_controller_->Cancel(MenuController::EXIT_ALL); + return POST_DISPATCH_QUIT_LOOP; + + default: + break; + } + return POST_DISPATCH_PERFORM_DEFAULT | + (menu_controller_->exit_type() == MenuController::EXIT_NONE + ? POST_DISPATCH_NONE + : POST_DISPATCH_QUIT_LOOP); +} + +} // namespace internal +} // namespace views diff --git a/ui/views/views.gyp b/ui/views/views.gyp index feb92d8942..77d3e8bc42 100644 --- a/ui/views/views.gyp +++ b/ui/views/views.gyp @@ -117,10 +117,13 @@ 'controls/menu/menu_config_win.cc', 'controls/menu/menu_controller.cc', 'controls/menu/menu_controller.h', - 'controls/menu/menu_controller_aura.cc', 'controls/menu/menu_controller_delegate.h', 'controls/menu/menu_delegate.cc', 'controls/menu/menu_delegate.h', + 'controls/menu/menu_message_pump_dispatcher.cc', + 'controls/menu/menu_message_pump_dispatcher.h', + 'controls/menu/menu_message_pump_dispatcher_linux.cc', + 'controls/menu/menu_message_pump_dispatcher_win.cc', 'controls/menu/menu_host.cc', 'controls/menu/menu_host.h', 'controls/menu/menu_host_root_view.cc', |