diff options
34 files changed, 1675 insertions, 52 deletions
diff --git a/skia/ext/canvas_paint.h b/skia/ext/canvas_paint.h index f052fb5..87118bd 100644 --- a/skia/ext/canvas_paint.h +++ b/skia/ext/canvas_paint.h @@ -14,7 +14,11 @@ #elif defined(__APPLE__) #include "skia/ext/canvas_paint_mac.h" #elif defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__sun) +#if defined(USE_WAYLAND) +#include "skia/ext/canvas_paint_wayland.h" +#else #include "skia/ext/canvas_paint_linux.h" #endif +#endif #endif // SKIA_EXT_CANVAS_PAINT_H_ diff --git a/skia/ext/canvas_paint_wayland.h b/skia/ext/canvas_paint_wayland.h new file mode 100644 index 0000000..2afdb01 --- /dev/null +++ b/skia/ext/canvas_paint_wayland.h @@ -0,0 +1,109 @@ +// Copyright (c) 2011 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 SKIA_EXT_CANVAS_PAINT_WAYLAND_H_ +#define SKIA_EXT_CANVAS_PAINT_WAYLAND_H_ +#pragma once + +#include "base/logging.h" +#include "skia/ext/platform_canvas.h" + +namespace skia { + +// A class designed to translate skia painting into a region in a Wayland window +// surface. On construction, it will set up a context for painting into, and on +// destruction, it will commit it to the Wayland window surface. +template <class T> +class CanvasPaintT : public T { + public: + // This constructor assumes the result is opaque. + CanvasPaintT(cairo_surface_t* cairo_window_surface, + cairo_rectangle_int_t* region) + : context_(NULL), + cairo_window_surface_(cairo_window_surface), + region_(region), + composite_alpha_(false) { + init(true); + } + + CanvasPaintT(cairo_surface_t* cairo_window_surface, + cairo_rectangle_int_t* region, + bool opaque) + : context_(NULL), + cairo_window_surface_(cairo_window_surface), + region_(region), + composite_alpha_(false) { + init(opaque); + } + + virtual ~CanvasPaintT() { + if (!is_empty()) { + T::restoreToCount(1); + + // Blit the dirty rect to the window. + CHECK(cairo_window_surface_); + cairo_t* cr = cairo_create(cairo_window_surface_); + CHECK(cr); + + if (composite_alpha_) + cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE); + + cairo_surface_t* source_surface = cairo_get_target(context_); + CHECK(source_surface); + // Flush cairo's cache of the surface. + cairo_surface_mark_dirty(source_surface); + cairo_set_source_surface(cr, source_surface, region_->x, region_->y); + cairo_rectangle(cr, + region_->x, + region_->y, + region_->width, + region_->height); + cairo_fill(cr); + cairo_destroy(cr); + } + } + + // Sets whether the bitmap is composited in such a way that the alpha channel + // is honored. This is only useful if you've enabled an RGBA colormap on the + // widget. The default is false. + void set_composite_alpha(bool composite_alpha) { + composite_alpha_ = composite_alpha; + } + + // Returns true if the invalid region is empty. The caller should call this + // function to determine if anything needs painting. + bool is_empty() const { + return region_->width == 0 && region_->height == 0; + } + + private: + void init(bool opaque) { + if (!T::initialize(region_->width, region_->height, opaque, NULL)) { + // Cause a deliberate crash; + CHECK(false); + } + + // Need to translate so that the dirty region appears at the origin of the + // surface. + T::translate(-SkIntToScalar(region_->x), -SkIntToScalar(region_->y)); + + context_ = BeginPlatformPaint(this); + } + + cairo_t* context_; + cairo_surface_t* cairo_window_surface_; + cairo_rectangle_int_t* region_; + // See description above setter. + bool composite_alpha_; + + // Disallow copy and assign. + CanvasPaintT(const CanvasPaintT&); + CanvasPaintT& operator=(const CanvasPaintT&); +}; + +typedef CanvasPaintT<PlatformCanvas> PlatformCanvasPaint; + +} // namespace skia + +#endif // SKIA_EXT_CANVAS_PAINT_WAYLAND_H_ diff --git a/ui/gfx/rect.cc b/ui/gfx/rect.cc index 5413711..96a8b0d 100644 --- a/ui/gfx/rect.cc +++ b/ui/gfx/rect.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -8,9 +8,12 @@ #include <windows.h> #elif defined(OS_MACOSX) #include <CoreGraphics/CGGeometry.h> -#elif defined(OS_POSIX) +#elif defined(USE_X11) #include <gdk/gdk.h> #endif +#if defined(USE_WAYLAND) +#include <cairo.h> +#endif #include <ostream> @@ -77,7 +80,7 @@ Rect& Rect::operator=(const CGRect& r) { set_height(r.size.height); return *this; } -#elif defined(OS_POSIX) +#elif defined(USE_X11) Rect::Rect(const GdkRectangle& r) : origin_(r.x, r.y) { set_width(r.width); @@ -91,6 +94,21 @@ Rect& Rect::operator=(const GdkRectangle& r) { return *this; } #endif +#if defined(USE_WAYLAND) +Rect::Rect(const cairo_rectangle_int_t& r) + : origin_(r.x, r.y) { + set_width(r.width); + set_height(r.height); +} + +Rect& Rect::operator=(const cairo_rectangle_int_t& r) { + origin_.SetPoint(r.x, r.y); + set_width(r.width); + set_height(r.height); + return *this; +} +#endif + void Rect::SetRect(int x, int y, int width, int height) { origin_.SetPoint(x, y); @@ -141,12 +159,18 @@ RECT Rect::ToRECT() const { CGRect Rect::ToCGRect() const { return CGRectMake(x(), y(), width(), height()); } -#elif defined(OS_POSIX) +#elif defined(USE_X11) GdkRectangle Rect::ToGdkRectangle() const { GdkRectangle r = {x(), y(), width(), height()}; return r; } #endif +#if defined(USE_WAYLAND) +cairo_rectangle_int_t Rect::ToCairoRectangle() const { + cairo_rectangle_int_t r = {x(), y(), width(), height()}; + return r; +} +#endif bool Rect::Contains(int point_x, int point_y) const { return (point_x >= x()) && (point_x < right()) && diff --git a/ui/gfx/rect.h b/ui/gfx/rect.h index fdb3088..f47456f 100644 --- a/ui/gfx/rect.h +++ b/ui/gfx/rect.h @@ -24,6 +24,10 @@ typedef struct tagRECT RECT; typedef struct _GdkRectangle GdkRectangle; #endif +#if defined(USE_WAYLAND) +typedef struct _cairo_rectangle_int cairo_rectangle_int_t; +#endif + namespace gfx { class Insets; @@ -40,6 +44,9 @@ class UI_EXPORT Rect { #elif defined(USE_X11) explicit Rect(const GdkRectangle& r); #endif +#if defined(USE_WAYLAND) + explicit Rect(const cairo_rectangle_int_t& r); +#endif explicit Rect(const gfx::Size& size); Rect(const gfx::Point& origin, const gfx::Size& size); @@ -52,6 +59,9 @@ class UI_EXPORT Rect { #elif defined(USE_X11) Rect& operator=(const GdkRectangle& r); #endif +#if defined(USE_WAYLAND) + Rect& operator=(const cairo_rectangle_int_t& r); +#endif int x() const { return origin_.x(); } void set_x(int x) { origin_.set_x(x); } @@ -119,6 +129,9 @@ class UI_EXPORT Rect { // Construct an equivalent CoreGraphics object. CGRect ToCGRect() const; #endif +#if defined(USE_WAYLAND) + cairo_rectangle_int_t ToCairoRectangle() const; +#endif // Returns true if the point identified by point_x and point_y falls inside // this rectangle. The point (x, y) is inside the rectangle, but the diff --git a/views/controls/combobox/native_combobox_wayland.cc b/views/controls/combobox/native_combobox_wayland.cc new file mode 100644 index 0000000..c54b068 --- /dev/null +++ b/views/controls/combobox/native_combobox_wayland.cc @@ -0,0 +1,15 @@ +// Copyright (c) 2011 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 "views/controls/combobox/native_combobox_views.h" + +namespace views { + +// static +NativeComboboxWrapper* NativeComboboxWrapper::CreateWrapper( + Combobox* combobox) { + return new NativeComboboxViews(combobox); +} + +} // namespace views diff --git a/views/controls/menu/menu_config_gtk.cc b/views/controls/menu/menu_config_linux.cc index c55fa91..c55fa91 100644 --- a/views/controls/menu/menu_config_gtk.cc +++ b/views/controls/menu/menu_config_linux.cc diff --git a/views/controls/menu/menu_controller.cc b/views/controls/menu/menu_controller.cc index 7cfbb3a..1858993 100644 --- a/views/controls/menu/menu_controller.cc +++ b/views/controls/menu/menu_controller.cc @@ -869,6 +869,13 @@ bool MenuController::Dispatch(const MSG& msg) { DispatchMessage(&msg); return exit_type_ == EXIT_NONE; } +#elif defined(USE_WAYLAND) +base::MessagePumpDispatcher::DispatchStatus + MenuController::Dispatch(ui::WaylandEvent* ev) { + return exit_type_ != EXIT_NONE ? + base::MessagePumpDispatcher::EVENT_QUIT : + base::MessagePumpDispatcher::EVENT_PROCESSED; +} #elif defined(TOUCH_UI) base::MessagePumpDispatcher::DispatchStatus MenuController::Dispatch(XEvent* xev) { diff --git a/views/controls/menu/menu_controller.h b/views/controls/menu/menu_controller.h index 35b7a78..91f4d79 100644 --- a/views/controls/menu/menu_controller.h +++ b/views/controls/menu/menu_controller.h @@ -219,6 +219,9 @@ class VIEWS_EXPORT MenuController : public MessageLoop::Dispatcher { // Dispatcher method. This returns true if the menu was canceled, or // if the message is such that the menu should be closed. virtual bool Dispatch(const MSG& msg); +#elif defined(USE_WAYLAND) + virtual base::MessagePumpDispatcher::DispatchStatus Dispatch( + ui::WaylandEvent* event); #elif defined(TOUCH_UI) virtual base::MessagePumpDispatcher::DispatchStatus Dispatch(XEvent* xevent); #else diff --git a/views/controls/menu/menu_image_util_gtk.cc b/views/controls/menu/menu_image_util_linux.cc index e2e3bfb..b2f5d97 100644 --- a/views/controls/menu/menu_image_util_gtk.cc +++ b/views/controls/menu/menu_image_util_linux.cc @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "views/controls/menu/menu_image_util_gtk.h" +#include "views/controls/menu/menu_image_util_linux.h" #include "base/i18n/rtl.h" #include "grit/ui_resources.h" diff --git a/views/controls/menu/menu_image_util_gtk.h b/views/controls/menu/menu_image_util_linux.h index f4c0ead..abf9bcb 100644 --- a/views/controls/menu/menu_image_util_gtk.h +++ b/views/controls/menu/menu_image_util_linux.h @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef VIEWS_CONTROLS_MENU_MENU_IMAGE_UTIL_GTK_H_ -#define VIEWS_CONTROLS_MENU_MENU_IMAGE_UTIL_GTK_H_ +#ifndef VIEWS_CONTROLS_MENU_MENU_IMAGE_UTIL_LINUX_H_ +#define VIEWS_CONTROLS_MENU_MENU_IMAGE_UTIL_LINUX_H_ #pragma once #include "third_party/skia/include/core/SkBitmap.h" @@ -19,6 +19,6 @@ const SkBitmap* GetRadioButtonImage(bool selected); // Returns the image for submenu arrow for current RTL setting. const SkBitmap* GetSubmenuArrowImage(); -} // namespace views +} // namespace views -#endif // VIEWS_CONTROLS_MENU_MENU_IMAGE_UTIL_GTK_H_ +#endif // VIEWS_CONTROLS_MENU_MENU_IMAGE_UTIL_LINUX_H_ diff --git a/views/controls/menu/menu_item_view_gtk.cc b/views/controls/menu/menu_item_view_linux.cc index 956a167..b90c7ce 100644 --- a/views/controls/menu/menu_item_view_gtk.cc +++ b/views/controls/menu/menu_item_view_linux.cc @@ -12,7 +12,7 @@ #include "ui/gfx/favicon_size.h" #include "views/controls/button/text_button.h" #include "views/controls/menu/menu_config.h" -#include "views/controls/menu/menu_image_util_gtk.h" +#include "views/controls/menu/menu_image_util_linux.h" #include "views/controls/menu/submenu_view.h" namespace views { diff --git a/views/controls/menu/menu_separator_gtk.cc b/views/controls/menu/menu_separator_linux.cc index 5283109..add1639 100644 --- a/views/controls/menu/menu_separator_gtk.cc +++ b/views/controls/menu/menu_separator_linux.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. diff --git a/views/controls/menu/native_menu_x.cc b/views/controls/menu/native_menu_linux.cc index b07389e..7556874 100644 --- a/views/controls/menu/native_menu_x.cc +++ b/views/controls/menu/native_menu_linux.cc @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "views/controls/menu/native_menu_x.h" +#include "views/controls/menu/native_menu_linux.h" #include "base/logging.h" #include "base/utf_string_conversions.h" @@ -14,17 +14,17 @@ namespace views { -NativeMenuX::NativeMenuX(Menu2* menu) +NativeMenuLinux::NativeMenuLinux(Menu2* menu) : model_(menu->model()), ALLOW_THIS_IN_INITIALIZER_LIST(root_(new MenuItemView(this))), menu_runner_(new MenuRunner(root_)) { } -NativeMenuX::~NativeMenuX() { +NativeMenuLinux::~NativeMenuLinux() { } // MenuWrapper implementation: -void NativeMenuX::RunMenuAt(const gfx::Point& point, int alignment) { +void NativeMenuLinux::RunMenuAt(const gfx::Point& point, int alignment) { // TODO: this should really return the value from MenuRunner. UpdateStates(); if (menu_runner_->RunMenuAt(NULL, NULL, gfx::Rect(point, gfx::Size()), @@ -34,46 +34,46 @@ void NativeMenuX::RunMenuAt(const gfx::Point& point, int alignment) { return; } -void NativeMenuX::CancelMenu() { +void NativeMenuLinux::CancelMenu() { NOTIMPLEMENTED(); } -void NativeMenuX::Rebuild() { +void NativeMenuLinux::Rebuild() { if (SubmenuView* submenu = root_->GetSubmenu()) submenu->RemoveAllChildViews(true); AddMenuItemsFromModel(root_, model_); } -void NativeMenuX::UpdateStates() { +void NativeMenuLinux::UpdateStates() { SubmenuView* submenu = root_->CreateSubmenu(); UpdateMenuFromModel(submenu, model_); } -gfx::NativeMenu NativeMenuX::GetNativeMenu() const { +gfx::NativeMenu NativeMenuLinux::GetNativeMenu() const { NOTIMPLEMENTED(); return NULL; } -MenuWrapper::MenuAction NativeMenuX::GetMenuAction() const { +MenuWrapper::MenuAction NativeMenuLinux::GetMenuAction() const { NOTIMPLEMENTED(); return MENU_ACTION_NONE; } -void NativeMenuX::AddMenuListener(MenuListener* listener) { +void NativeMenuLinux::AddMenuListener(MenuListener* listener) { NOTIMPLEMENTED(); } -void NativeMenuX::RemoveMenuListener(MenuListener* listener) { +void NativeMenuLinux::RemoveMenuListener(MenuListener* listener) { NOTIMPLEMENTED(); } -void NativeMenuX::SetMinimumWidth(int width) { +void NativeMenuLinux::SetMinimumWidth(int width) { NOTIMPLEMENTED(); } // MenuDelegate implementation -bool NativeMenuX::IsItemChecked(int cmd) const { +bool NativeMenuLinux::IsItemChecked(int cmd) const { int index; ui::MenuModel* model = model_; if (!ui::MenuModel::GetModelAndIndexForCommandId(cmd, &model, &index)) @@ -81,7 +81,7 @@ bool NativeMenuX::IsItemChecked(int cmd) const { return model->IsItemCheckedAt(index); } -bool NativeMenuX::IsCommandEnabled(int cmd) const { +bool NativeMenuLinux::IsCommandEnabled(int cmd) const { int index; ui::MenuModel* model = model_; if (!ui::MenuModel::GetModelAndIndexForCommandId(cmd, &model, &index)) @@ -89,7 +89,7 @@ bool NativeMenuX::IsCommandEnabled(int cmd) const { return model->IsEnabledAt(index); } -void NativeMenuX::ExecuteCommand(int cmd) { +void NativeMenuLinux::ExecuteCommand(int cmd) { int index; ui::MenuModel* model = model_; if (!ui::MenuModel::GetModelAndIndexForCommandId(cmd, &model, &index)) @@ -97,7 +97,7 @@ void NativeMenuX::ExecuteCommand(int cmd) { model->ActivatedAt(index); } -bool NativeMenuX::GetAccelerator(int id, views::Accelerator* accelerator) { +bool NativeMenuLinux::GetAccelerator(int id, views::Accelerator* accelerator) { int index; ui::MenuModel* model = model_; if (!ui::MenuModel::GetModelAndIndexForCommandId(id, &model, &index)) @@ -113,8 +113,8 @@ bool NativeMenuX::GetAccelerator(int id, views::Accelerator* accelerator) { } // private -void NativeMenuX::AddMenuItemsFromModel(MenuItemView* parent, - ui::MenuModel* model) { +void NativeMenuLinux::AddMenuItemsFromModel(MenuItemView* parent, + ui::MenuModel* model) { for (int i = 0; i < model->GetItemCount(); ++i) { int index = i + model->GetFirstItemIndex(NULL); MenuItemView* child = parent->AppendMenuItemFromModel(model, index, @@ -126,8 +126,8 @@ void NativeMenuX::AddMenuItemsFromModel(MenuItemView* parent, } } -void NativeMenuX::UpdateMenuFromModel(SubmenuView* menu, - ui::MenuModel* model) { +void NativeMenuLinux::UpdateMenuFromModel(SubmenuView* menu, + ui::MenuModel* model) { for (int i = 0, sep = 0; i < model->GetItemCount(); ++i) { int index = i + model->GetFirstItemIndex(NULL); if (model->GetTypeAt(index) == ui::MenuModel::TYPE_SEPARATOR) { @@ -162,7 +162,7 @@ void NativeMenuX::UpdateMenuFromModel(SubmenuView* menu, // static MenuWrapper* MenuWrapper::CreateWrapper(Menu2* menu) { - return new NativeMenuX(menu); + return new NativeMenuLinux(menu); } } // namespace views diff --git a/views/controls/menu/native_menu_x.h b/views/controls/menu/native_menu_linux.h index 34ae894..bfec464 100644 --- a/views/controls/menu/native_menu_x.h +++ b/views/controls/menu/native_menu_linux.h @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef VIEWS_CONTROLS_MENU_NATIVE_MENU_X_H_ -#define VIEWS_CONTROLS_MENU_NATIVE_MENU_X_H_ +#ifndef VIEWS_CONTROLS_MENU_NATIVE_MENU_LINUX_H_ +#define VIEWS_CONTROLS_MENU_NATIVE_MENU_LINUX_H_ #pragma once #include "views/controls/menu/menu_delegate.h" @@ -19,11 +19,11 @@ namespace views { class MenuRunner; // A non-GTK implementation of MenuWrapper, used currently for touchui. -class NativeMenuX : public MenuWrapper, - public MenuDelegate { +class NativeMenuLinux : public MenuWrapper, + public MenuDelegate { public: - explicit NativeMenuX(Menu2* menu); - virtual ~NativeMenuX(); + explicit NativeMenuLinux(Menu2* menu); + virtual ~NativeMenuLinux(); // Overridden from MenuWrapper: virtual void RunMenuAt(const gfx::Point& point, int alignment); @@ -51,9 +51,9 @@ class NativeMenuX : public MenuWrapper, MenuItemView* root_; scoped_ptr<MenuRunner> menu_runner_; - DISALLOW_COPY_AND_ASSIGN(NativeMenuX); + DISALLOW_COPY_AND_ASSIGN(NativeMenuLinux); }; } // namespace views -#endif // VIEWS_CONTROLS_MENU_NATIVE_MENU_X_H_ +#endif // VIEWS_CONTROLS_MENU_NATIVE_MENU_LINUX_H_ diff --git a/views/controls/native/native_view_host_wayland.cc b/views/controls/native/native_view_host_wayland.cc new file mode 100644 index 0000000..11e6a2b --- /dev/null +++ b/views/controls/native/native_view_host_wayland.cc @@ -0,0 +1,16 @@ +// Copyright (c) 2011 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 "views/controls/native/native_view_host.h" +#include "views/controls/native/native_view_host_views.h" + +namespace views { + +// static +NativeViewHostWrapper* NativeViewHostWrapper::CreateWrapper( + NativeViewHost* host) { + return new NativeViewHostViews(host); +} + +} // namespace views diff --git a/views/controls/scrollbar/native_scroll_bar_wayland.cc b/views/controls/scrollbar/native_scroll_bar_wayland.cc new file mode 100644 index 0000000..706647f --- /dev/null +++ b/views/controls/scrollbar/native_scroll_bar_wayland.cc @@ -0,0 +1,30 @@ +// Copyright (c) 2011 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 "views/controls/scrollbar/native_scroll_bar.h" +#include "views/controls/scrollbar/native_scroll_bar_views.h" +#include "views/controls/scrollbar/native_scroll_bar_wrapper.h" + +namespace views { + +//////////////////////////////////////////////////////////////////////////////// +// NativewScrollBarWrapper, public: + +// static +NativeScrollBarWrapper* NativeScrollBarWrapper::CreateWrapper( + NativeScrollBar* scroll_bar) { + return new NativeScrollBarViews(scroll_bar); +} + +// static +int NativeScrollBarWrapper::GetHorizontalScrollBarHeight() { + return 20; +} + +// static +int NativeScrollBarWrapper::GetVerticalScrollBarWidth() { + return 20; +} + +} // namespace views diff --git a/views/controls/textfield/native_textfield_wayland.cc b/views/controls/textfield/native_textfield_wayland.cc new file mode 100644 index 0000000..d5869dc --- /dev/null +++ b/views/controls/textfield/native_textfield_wayland.cc @@ -0,0 +1,20 @@ +// Copyright (c) 2011 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 "base/logging.h" +#include "views/controls/textfield/native_textfield_views.h" +#include "views/controls/textfield/textfield.h" + +namespace views { + +/////////////////////////////////////////////////////////////////////////////// +// NativeTextfieldWrapper: + +// static +NativeTextfieldWrapper* NativeTextfieldWrapper::CreateWrapper( + Textfield* field) { + return new NativeTextfieldViews(field); +} + +} // namespace views diff --git a/views/desktop/desktop_main.cc b/views/desktop/desktop_main.cc index 09db616..ebee039 100644 --- a/views/desktop/desktop_main.cc +++ b/views/desktop/desktop_main.cc @@ -17,6 +17,12 @@ #include <ole2.h> #endif +#if defined(USE_WAYLAND) +#include "ui/gfx/gl/gl_surface_egl.h" +#include "ui/wayland/wayland_display.h" +#include "ui/wayland/wayland_message_pump.h" +#endif + int main(int argc, char** argv) { #if defined(OS_WIN) OleInitialize(NULL); @@ -24,8 +30,10 @@ int main(int argc, char** argv) { // Initializes gtk stuff. g_thread_init(NULL); g_type_init(); +#if !defined(USE_WAYLAND) gtk_init(&argc, &argv); #endif +#endif CommandLine::Init(argc, argv); @@ -39,6 +47,16 @@ int main(int argc, char** argv) { ResourceBundle::InitSharedInstance("en-US"); +#if defined(USE_WAYLAND) + // Wayland uses EGL for drawing, so we need to initialize this as early as + // possible. + if (!gfx::GLSurface::InitializeOneOff()) { + LOG(ERROR) << "Failed to initialize GLSurface"; + return -1; + } + ui::WaylandMessagePump wayland_message_pump( + ui::WaylandDisplay::GetDisplay(gfx::GLSurfaceEGL::GetNativeDisplay())); +#endif MessageLoop main_message_loop(MessageLoop::TYPE_UI); views::desktop::DesktopViewsDelegate views_delegate; diff --git a/views/desktop/desktop_window_view.cc b/views/desktop/desktop_window_view.cc index e2bbaef..7562e67 100644 --- a/views/desktop/desktop_window_view.cc +++ b/views/desktop/desktop_window_view.cc @@ -19,6 +19,8 @@ #include "views/widget/native_widget_aura.h" #elif defined(OS_WIN) #include "views/widget/native_widget_win.h" +#elif defined(USE_WAYLAND) +#include "views/widget/native_widget_wayland.h" #elif defined(TOOLKIT_USES_GTK) #include "views/widget/native_widget_gtk.h" #endif @@ -143,6 +145,8 @@ void DesktopWindowView::CreateDesktopWindow(DesktopType type) { params.native_widget = new views::NativeWidgetAura(window); #elif defined(OS_WIN) params.native_widget = new views::NativeWidgetWin(window); +#elif defined(USE_WAYLAND) + params.native_widget = new views::NativeWidgetWayland(window); #elif defined(TOOLKIT_USES_GTK) params.native_widget = new views::NativeWidgetGtk(window); params.maximize = true; diff --git a/views/events/event_wayland.cc b/views/events/event_wayland.cc new file mode 100644 index 0000000..92b5482 --- /dev/null +++ b/views/events/event_wayland.cc @@ -0,0 +1,215 @@ +// Copyright (c) 2011 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 "views/events/event.h" + +#include <X11/Xlib.h> + +#include "base/logging.h" +#include "ui/base/keycodes/keyboard_code_conversion_x.h" +#include "ui/wayland/events/wayland_event.h" + +namespace views { + +namespace { + +static int kWheelScrollAmount = 53; + +ui::EventType EventTypeFromNative(NativeEvent native_event) { + switch (native_event->type) { + case ui::WAYLAND_BUTTON: + switch (native_event->button.button) { + case ui::LEFT_BUTTON: + case ui::RIGHT_BUTTON: + case ui::MIDDLE_BUTTON: + return native_event->button.state ? ui::ET_MOUSE_PRESSED + : ui::ET_MOUSE_RELEASED; + case ui::SCROLL_UP: + case ui::SCROLL_DOWN: + return ui::ET_MOUSEWHEEL; + default: + break; + } + break; + case ui::WAYLAND_KEY: + return native_event->key.state ? ui::ET_KEY_PRESSED + : ui::ET_KEY_RELEASED; + case ui::WAYLAND_MOTION: + return ui::ET_MOUSE_MOVED; + case ui::WAYLAND_POINTER_FOCUS: + return native_event->pointer_focus.state ? ui::ET_MOUSE_ENTERED + : ui::ET_MOUSE_EXITED; + case ui::WAYLAND_KEYBOARD_FOCUS: + return ui::ET_UNKNOWN; + default: + break; + } + return ui::ET_UNKNOWN; +} + +gfx::Point GetMouseEventLocation(NativeEvent native_event) { + switch (native_event->type) { + case ui::WAYLAND_BUTTON: + return gfx::Point(native_event->button.x, native_event->button.y); + case ui::WAYLAND_MOTION: + return gfx::Point(native_event->motion.x, native_event->motion.y); + case ui::WAYLAND_POINTER_FOCUS: + return gfx::Point(native_event->pointer_focus.x, + native_event->pointer_focus.y); + default: + return gfx::Point(0, 0); + } +} + +int GetEventFlagsFromState(unsigned int state) { + int flags = 0; + if (state & ControlMask) + flags |= ui::EF_CONTROL_DOWN; + if (state & ShiftMask) + flags |= ui::EF_SHIFT_DOWN; + if (state & Mod1Mask) + flags |= ui::EF_ALT_DOWN; + if (state & LockMask) + flags |= ui::EF_CAPS_LOCK_DOWN; + if (state & Button1Mask) + flags |= ui::EF_LEFT_BUTTON_DOWN; + if (state & Button2Mask) + flags |= ui::EF_MIDDLE_BUTTON_DOWN; + if (state & Button3Mask) + flags |= ui::EF_RIGHT_BUTTON_DOWN; + + return flags; +} + +int GetButtonEventFlagsFromNativeEvent(NativeEvent native_event) { + // TODO(dnicoara): Need to add double click. + int flags = 0; + switch (native_event->button.button) { + case ui::LEFT_BUTTON: + return flags | ui::EF_LEFT_BUTTON_DOWN; + case ui::MIDDLE_BUTTON: + return flags | ui::EF_MIDDLE_BUTTON_DOWN; + case ui::RIGHT_BUTTON: + return flags | ui::EF_RIGHT_BUTTON_DOWN; + } + return flags; +} + +int GetEventFlagsFromNativeEvent(NativeEvent native_event) { + switch (native_event->type) { + case ui::WAYLAND_BUTTON: + return GetButtonEventFlagsFromNativeEvent(native_event) | + GetEventFlagsFromState(native_event->button.modifiers); + case ui::WAYLAND_KEY: + return GetEventFlagsFromState(native_event->key.modifiers); + case ui::WAYLAND_MOTION: + return GetEventFlagsFromState(native_event->motion.modifiers); + case ui::WAYLAND_KEYBOARD_FOCUS: + return GetEventFlagsFromState(native_event->keyboard_focus.modifiers); + default: + return 0; + } +} + +int GetMouseWheelOffset(NativeEvent native_event) { + if (native_event->button.button == ui::SCROLL_UP) { + return kWheelScrollAmount; + } else { + return -kWheelScrollAmount; + } +} + +} // namespace + +//////////////////////////////////////////////////////////////////////////////// +// Event, private: + +void Event::Init() { + native_event_ = NULL; + native_event_2_ = NULL; +} + +void Event::InitWithNativeEvent(NativeEvent native_event) { + native_event_ = native_event; + // TODO(dnicoara): Remove once we rid views of Gtk/Gdk. + native_event_2_ = NULL; +} + +void Event::InitWithNativeEvent2(NativeEvent2 native_event_2, + FromNativeEvent2) { + native_event_2_ = NULL; + // TODO(dnicoara): Remove once we rid views of Gtk/Gdk. + native_event_2_ = native_event_2; +} + +//////////////////////////////////////////////////////////////////////////////// +// MouseEvent, public: + +MouseEvent::MouseEvent(NativeEvent native_event) + : LocatedEvent(native_event) { +} + +MouseEvent::MouseEvent(NativeEvent2 native_event_2, + FromNativeEvent2 from_native) + : LocatedEvent(native_event_2, from_native) { + // TODO(dnicoara): Remove once we rid views of Gtk/Gdk. + NOTREACHED(); +} + +//////////////////////////////////////////////////////////////////////////////// +// LocatedEvent, protected: + +LocatedEvent::LocatedEvent(NativeEvent native_event) + : Event(native_event, EventTypeFromNative(native_event), + GetEventFlagsFromNativeEvent(native_event)), + location_(GetMouseEventLocation(native_event)) { +} + +LocatedEvent::LocatedEvent(NativeEvent2 native_event_2, + FromNativeEvent2 from_native) + : Event(native_event_2, ui::ET_UNKNOWN, 0, from_native) { + // TODO(dnicoara) Remove once we rid views of Gtk. + NOTREACHED(); +} + +////////////////////////////////////////////////////////////////////////////// +// KeyEvent, public: + + +KeyEvent::KeyEvent(NativeEvent native_event) + : Event(native_event, EventTypeFromNative(native_event), + GetEventFlagsFromNativeEvent(native_event)), + key_code_(ui::KeyboardCodeFromXKeysym(native_event->key.sym)) { +} + +KeyEvent::KeyEvent(NativeEvent2 native_event_2, FromNativeEvent2 from_native) + : Event(native_event_2, ui::ET_UNKNOWN, 0, from_native) { + // TODO(dnicoara) Remove once we rid views of Gtk. + NOTREACHED(); +} + +uint16 KeyEvent::GetCharacter() const { + return GetCharacterFromKeyCode(key_code_, flags()); +} + +uint16 KeyEvent::GetUnmodifiedCharacter() const { + return GetCharacterFromKeyCode(key_code_, flags() & ui::EF_SHIFT_DOWN); +} + +////////////////////////////////////////////////////////////////////////////// +// MouseWheelEvent, public: + +MouseWheelEvent::MouseWheelEvent(NativeEvent native_event) + : MouseEvent(native_event), + offset_(GetMouseWheelOffset(native_event)) { +} + +MouseWheelEvent::MouseWheelEvent(NativeEvent2 native_event_2, + FromNativeEvent2 from_native) + : MouseEvent(native_event_2, from_native) { + // TODO(dnicoara) Remove once we rid views of Gtk. + NOTREACHED(); +} + +} // namespace views diff --git a/views/focus/accelerator_handler.h b/views/focus/accelerator_handler.h index b90bc84..9472dc7 100644 --- a/views/focus/accelerator_handler.h +++ b/views/focus/accelerator_handler.h @@ -20,7 +20,7 @@ namespace views { -#if defined(TOUCH_UI) +#if defined(TOUCH_UI) && !defined(USE_WAYLAND) // Dispatch an XEvent to the RootView. Return true if the event was dispatched // and handled, false otherwise. bool VIEWS_EXPORT DispatchXEvent(XEvent* xevent); @@ -40,6 +40,9 @@ class VIEWS_EXPORT AcceleratorHandler : public MessageLoop::Dispatcher { // focus manager #if defined(OS_WIN) virtual bool Dispatch(const MSG& msg); +#elif defined(USE_WAYLAND) + virtual base::MessagePumpDispatcher::DispatchStatus Dispatch( + ui::WaylandEvent* ev); #elif defined(TOUCH_UI) virtual base::MessagePumpDispatcher::DispatchStatus Dispatch(XEvent* xev); #else diff --git a/views/focus/accelerator_handler_wayland.cc b/views/focus/accelerator_handler_wayland.cc new file mode 100644 index 0000000..1039570 --- /dev/null +++ b/views/focus/accelerator_handler_wayland.cc @@ -0,0 +1,19 @@ +// Copyright (c) 2011 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 "views/focus/accelerator_handler.h" + +#include "views/accelerator.h" +#include "views/focus/focus_manager.h" + +namespace views { + +AcceleratorHandler::AcceleratorHandler() {} + +base::MessagePumpDispatcher::DispatchStatus + AcceleratorHandler::Dispatch(ui::WaylandEvent* ev) { + return base::MessagePumpDispatcher::EVENT_IGNORED; +} + +} // namespace views diff --git a/views/ime/input_method_wayland.cc b/views/ime/input_method_wayland.cc new file mode 100644 index 0000000..20d3ff2 --- /dev/null +++ b/views/ime/input_method_wayland.cc @@ -0,0 +1,76 @@ +// Copyright (c) 2011 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 "views/ime/input_method_wayland.h" + +#include "views/widget/widget.h" + +namespace views { + +InputMethodWayland::InputMethodWayland( + internal::InputMethodDelegate *delegate) { + set_delegate(delegate); +} + +void InputMethodWayland::DispatchKeyEvent(const KeyEvent& key) { + if (!GetTextInputClient()) { + DispatchKeyEventPostIME(key); + return; + } + + if (key.type() == ui::ET_KEY_PRESSED) { + ProcessKeyPressEvent(key); + } else if (key.type() == ui::ET_KEY_RELEASED) { + DispatchKeyEventPostIME(key); + } +} + +void InputMethodWayland::OnTextInputTypeChanged(View* view) { + NOTIMPLEMENTED(); +} + +void InputMethodWayland::OnCaretBoundsChanged(View* view) { + NOTIMPLEMENTED(); +} + +void InputMethodWayland::CancelComposition(View* view) { + NOTIMPLEMENTED(); +} + +std::string InputMethodWayland::GetInputLocale() { + return std::string(""); +} + +base::i18n::TextDirection InputMethodWayland::GetInputTextDirection() { + return base::i18n::UNKNOWN_DIRECTION; +} + +bool InputMethodWayland::IsActive() { + return true; +} + +////////////////////////////////////////////////////////////////////////////// +// InputMethodWayland private + +void InputMethodWayland::ProcessKeyPressEvent(const KeyEvent& key) { + const View* old_focused_view = focused_view(); + DispatchKeyEventPostIME(key); + + // We shouldn't dispatch the character anymore if the key event caused focus + // change. + if (old_focused_view != focused_view()) + return; + + // If a key event was not filtered by |context_| or |context_simple_|, then + // it means the key event didn't generate any result text. For some cases, + // the key event may still generate a valid character, eg. a control-key + // event (ctrl-a, return, tab, etc.). We need to send the character to the + // focused text input client by calling TextInputClient::InsertChar(). + char16 ch = key.GetCharacter(); + TextInputClient* client = GetTextInputClient(); + if (ch && client) + client->InsertChar(ch, key.flags()); +} + +} // namespace views diff --git a/views/ime/input_method_wayland.h b/views/ime/input_method_wayland.h new file mode 100644 index 0000000..60dac30 --- /dev/null +++ b/views/ime/input_method_wayland.h @@ -0,0 +1,36 @@ +// Copyright (c) 2011 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 VIEWS_IME_INPUT_METHOD_WAYLAND_H_ +#define VIEWS_IME_INPUT_METHOD_WAYLAND_H_ +#pragma once + +#include <string> + +#include "views/ime/input_method_base.h" + +namespace views { + +class InputMethodWayland : public InputMethodBase { + public: + explicit InputMethodWayland(internal::InputMethodDelegate *delegate); + + virtual void DispatchKeyEvent(const KeyEvent& key) OVERRIDE; + virtual void OnTextInputTypeChanged(View* view) OVERRIDE; + virtual void OnCaretBoundsChanged(View* view) OVERRIDE; + virtual void CancelComposition(View* view) OVERRIDE; + virtual std::string GetInputLocale() OVERRIDE; + virtual base::i18n::TextDirection GetInputTextDirection() OVERRIDE; + virtual bool IsActive() OVERRIDE; + + private: + + void ProcessKeyPressEvent(const KeyEvent& key); + + DISALLOW_COPY_AND_ASSIGN(InputMethodWayland); +}; + +} // namespace views + +#endif // VIEWS_IME_INPUT_METHOD_WAYLAND_H_ diff --git a/views/metrics_wayland.cc b/views/metrics_wayland.cc new file mode 100644 index 0000000..7d3beb1 --- /dev/null +++ b/views/metrics_wayland.cc @@ -0,0 +1,17 @@ +// Copyright (c) 2011 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 "views/metrics.h" + +namespace views { + +int GetDoubleClickInterval() { + return 500; +} + +int GetMenuShowDelay() { + return kDefaultMenuShowDelay; +} + +} // namespace views diff --git a/views/mouse_watcher.cc b/views/mouse_watcher.cc index 810db69..83fe75d 100644 --- a/views/mouse_watcher.cc +++ b/views/mouse_watcher.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -11,6 +11,10 @@ #include "views/view.h" #include "views/widget/widget.h" +#if defined(USE_WAYLAND) +#include "ui/wayland/events/wayland_event.h" +#endif + namespace views { // Amount of time between when the mouse moves outside the view's zone and when @@ -56,6 +60,22 @@ class MouseWatcher::Observer : public MessageLoopForUI::Observer { break; } } +#elif defined(USE_WAYLAND) + MessageLoopForUI::Observer::EventStatus WillProcessEvent( + ui::WaylandEvent* event) { + switch (event->type) { + case ui::WAYLAND_MOTION: + HandleGlobalMouseMoveEvent(false); + break; + case ui::WAYLAND_POINTER_FOCUS: + if (!event->pointer_focus.state) + HandleGlobalMouseMoveEvent(true); + break; + default: + break; + } + return EVENT_CONTINUE; + } #else void WillProcessEvent(GdkEvent* event) { } diff --git a/views/native_types.h b/views/native_types.h index 0941879..a5070e7 100644 --- a/views/native_types.h +++ b/views/native_types.h @@ -14,6 +14,11 @@ typedef union _GdkEvent GdkEvent; #if defined(USE_X11) typedef union _XEvent XEvent; #endif +#if defined(USE_WAYLAND) +namespace ui { +union WaylandEvent; +} +#endif #if defined(USE_AURA) namespace aura { @@ -40,9 +45,15 @@ typedef aura::Event* NativeEvent; #elif defined(OS_WIN) typedef MSG NativeEvent; #elif defined(OS_LINUX) + +#if defined(USE_WAYLAND) +typedef ui::WaylandEvent* NativeEvent; +#else typedef GdkEvent* NativeEvent; #endif +#endif + #if defined(USE_X11) typedef XEvent* NativeEvent2; #else diff --git a/views/view_wayland.cc b/views/view_wayland.cc new file mode 100644 index 0000000..7524858 --- /dev/null +++ b/views/view_wayland.cc @@ -0,0 +1,24 @@ +// Copyright (c) 2011 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 "views/view.h" + +#include "base/logging.h" + +namespace views { + +gfx::NativeViewAccessible View::GetNativeViewAccessible() { + NOTIMPLEMENTED(); + return NULL; +} + +int View::GetHorizontalDragThreshold() { + return 8; +} + +int View::GetVerticalDragThreshold() { + return GetHorizontalDragThreshold(); +} + +} // namespace views diff --git a/views/views.gyp b/views/views.gyp index 0b91db6..61ce97b 100644 --- a/views/views.gyp +++ b/views/views.gyp @@ -86,6 +86,7 @@ 'controls/combobox/native_combobox_gtk.h', 'controls/combobox/native_combobox_views.cc', 'controls/combobox/native_combobox_views.h', + 'controls/combobox/native_combobox_wayland.cc', 'controls/combobox/native_combobox_win.cc', 'controls/combobox/native_combobox_win.h', 'controls/combobox/native_combobox_wrapper.h', @@ -104,7 +105,7 @@ 'controls/menu/menu_2.h', 'controls/menu/menu_config.cc', 'controls/menu/menu_config.h', - 'controls/menu/menu_config_gtk.cc', + 'controls/menu/menu_config_linux.cc', 'controls/menu/menu_config_win.cc', 'controls/menu/menu_controller.cc', 'controls/menu/menu_controller.h', @@ -119,7 +120,7 @@ 'controls/menu/menu_host_root_view.h', 'controls/menu/menu_item_view.cc', 'controls/menu/menu_item_view.h', - 'controls/menu/menu_item_view_gtk.cc', + 'controls/menu/menu_item_view_linux.cc', 'controls/menu/menu_item_view_win.cc', 'controls/menu/menu_model_adapter.cc', 'controls/menu/menu_model_adapter.h', @@ -128,7 +129,7 @@ 'controls/menu/menu_scroll_view_container.cc', 'controls/menu/menu_scroll_view_container.h', 'controls/menu/menu_separator.h', - 'controls/menu/menu_separator_gtk.cc', + 'controls/menu/menu_separator_linux.cc', 'controls/menu/menu_separator_win.cc', 'controls/menu/menu_win.cc', 'controls/menu/menu_win.h', @@ -137,14 +138,14 @@ 'controls/menu/native_menu_gtk.h', 'controls/menu/native_menu_host.h', 'controls/menu/native_menu_host_delegate.h', + 'controls/menu/native_menu_linux.cc', + 'controls/menu/native_menu_linux.h', 'controls/menu/native_menu_win.cc', 'controls/menu/native_menu_win.h', - 'controls/menu/native_menu_x.cc', - 'controls/menu/native_menu_x.h', 'controls/menu/nested_dispatcher_gtk.cc', 'controls/menu/nested_dispatcher_gtk.h', - 'controls/menu/menu_image_util_gtk.cc', - 'controls/menu/menu_image_util_gtk.h', + 'controls/menu/menu_image_util_linux.cc', + 'controls/menu/menu_image_util_linux.h', 'controls/menu/submenu_view.cc', 'controls/menu/submenu_view.h', 'controls/menu/view_menu_delegate.h', @@ -164,6 +165,7 @@ 'controls/native/native_view_host_win.h', 'controls/native/native_view_host_views.cc', 'controls/native/native_view_host_views.h', + 'controls/native/native_view_host_wayland.cc', 'controls/native/native_view_host_wrapper.h', 'controls/progress_bar.h', 'controls/progress_bar.cc', @@ -183,6 +185,7 @@ 'controls/scrollbar/native_scroll_bar_gtk.h', 'controls/scrollbar/native_scroll_bar_views.cc', 'controls/scrollbar/native_scroll_bar_views.h', + 'controls/scrollbar/native_scroll_bar_wayland.cc', 'controls/scrollbar/native_scroll_bar_win.cc', 'controls/scrollbar/native_scroll_bar_win.h', 'controls/scrollbar/native_scroll_bar_wrapper.h', @@ -225,6 +228,7 @@ 'controls/textfield/textfield_views_model.h', 'controls/textfield/native_textfield_gtk.cc', 'controls/textfield/native_textfield_gtk.h', + 'controls/textfield/native_textfield_wayland.cc', 'controls/textfield/native_textfield_win.cc', 'controls/textfield/native_textfield_win.h', 'controls/textfield/native_textfield_wrapper.h', @@ -245,6 +249,7 @@ 'events/event.h', 'events/event_aura.cc', 'events/event_gtk.cc', + 'events/event_wayland.cc', 'events/event_win.cc', 'events/event_utils_win.cc', 'events/event_utils_win.h', @@ -253,6 +258,7 @@ 'focus/accelerator_handler_aura.cc', 'focus/accelerator_handler_gtk.cc', 'focus/accelerator_handler_touch.cc', + 'focus/accelerator_handler_wayland.cc', 'focus/accelerator_handler_win.cc', 'focus/external_focus_tracker.cc', 'focus/external_focus_tracker.h', @@ -276,6 +282,8 @@ 'ime/input_method_gtk.h', 'ime/input_method_ibus.cc', 'ime/input_method_ibus.h', + 'ime/input_method_wayland.cc', + 'ime/input_method_wayland.h', 'ime/input_method_win.cc', 'ime/input_method_win.h', 'ime/mock_input_method.cc', @@ -299,6 +307,7 @@ 'metrics.cc', 'metrics.h', 'metrics_gtk.cc', + 'metrics_wayland.cc', 'metrics_win.cc', 'mouse_watcher.cc', 'mouse_watcher.h', @@ -325,6 +334,7 @@ 'view_gtk.cc', 'view_text_utils.cc', 'view_text_utils.h', + 'view_wayland.cc', 'view_win.cc', 'views_delegate.h', 'widget/aero_tooltip_manager.cc', @@ -364,6 +374,8 @@ 'widget/native_widget_private.h', 'widget/native_widget_gtk.cc', 'widget/native_widget_gtk.h', + 'widget/native_widget_wayland.cc', + 'widget/native_widget_wayland.h', 'widget/native_widget_view.cc', 'widget/native_widget_view.h', 'widget/native_widget_views.cc', @@ -396,6 +408,22 @@ '<(DEPTH)/third_party/wtl/include', ], 'conditions': [ + ['use_wayland == 1', { + 'dependencies': [ + '../ui/wayland/wayland.gyp:wayland', + ], + 'sources/': [ + ['exclude', '_(gtk|x)\\.cc$'], + ['exclude', '/(gtk|x)_[^/]*\\.cc$'], + ['exclude', 'focus/accelerator_handler_touch.cc'], + ['exclude', 'touchui/touch_factory.cc'], + ['exclude', 'touchui/touch_factory.h'], + ['include', 'controls/menu/native_menu_linux.cc'], + ['include', 'controls/menu/native_menu_linux.h'], + ['include', 'drag_utils_gtk.cc'], + ['include', 'widget/tooltip_manager_views.cc'], + ], + }], ['use_aura==1', { 'dependencies': [ '../aura/aura.gyp:aura', @@ -448,8 +476,8 @@ }], ['touchui==0', { 'sources!': [ - 'controls/menu/native_menu_x.cc', - 'controls/menu/native_menu_x.h', + 'controls/menu/native_menu_linux.cc', + 'controls/menu/native_menu_linux.h', 'widget/tooltip_manager_views.cc', 'touchui/touch_selection_controller_impl.cc', 'touchui/touch_selection_controller_impl.h', diff --git a/views/widget/native_widget_wayland.cc b/views/widget/native_widget_wayland.cc new file mode 100644 index 0000000..ec462c6 --- /dev/null +++ b/views/widget/native_widget_wayland.cc @@ -0,0 +1,677 @@ +// Copyright (c) 2011 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 "views/widget/native_widget_wayland.h" + +#include <cairo.h> +#include <cairo-gl.h> +#include <EGL/egl.h> +#include <GL/gl.h> +#include <wayland-egl.h> + +#include <algorithm> +#include <list> + +#include "base/memory/scoped_ptr.h" +#include "ui/base/view_prop.h" +#include "ui/gfx/canvas_skia_paint.h" +#include "ui/gfx/compositor/compositor.h" +#include "ui/gfx/gl/gl_surface.h" +#include "ui/gfx/gl/gl_surface_egl.h" +#include "ui/wayland/events/wayland_event.h" +#include "ui/wayland/wayland_display.h" +#include "ui/wayland/wayland_input_device.h" +#include "ui/wayland/wayland_screen.h" +#include "ui/wayland/wayland_window.h" +#include "views/ime/input_method_wayland.h" +#include "views/views_delegate.h" +#include "views/widget/native_widget_views.h" +#include "views/widget/root_view.h" +#include "views/widget/tooltip_manager_views.h" + +using ui::ViewProp; + +namespace views { + +namespace { + +// Links the WaylandWidget to its NativeWidget. +const char* const kNativeWidgetKey = "__VIEWS_NATIVE_WIDGET__"; + +} // namespace + +NativeWidgetWayland::NativeWidgetWayland( + internal::NativeWidgetDelegate* delegate) + : delegate_(delegate), + ALLOW_THIS_IN_INITIALIZER_LIST(close_widget_factory_(this)), + ownership_(Widget::InitParams::NATIVE_WIDGET_OWNS_WIDGET), + has_mouse_capture_(false), + wayland_display_( + ui:: WaylandDisplay::GetDisplay(gfx::GLSurfaceEGL::GetNativeDisplay())), + wayland_window_(new ui::WaylandWindow(this, wayland_display_)), + surface_data_key_(), + damage_area_() { +} + +NativeWidgetWayland::~NativeWidgetWayland() { + if (ownership_ == Widget::InitParams::NATIVE_WIDGET_OWNS_WIDGET) + delete delegate_; + + if (!View::get_use_acceleration_when_possible()) { + cairo_surface_destroy(cairo_surface_); + cairo_device_destroy(device_); + } + + if (egl_window_) + wl_egl_window_destroy(egl_window_); + + if (wayland_window_) + delete wayland_window_; +} + +void NativeWidgetWayland::InitNativeWidget(const Widget::InitParams& params) { + // Cannot create a window with a size smaller than 1x1 + allocation_.set_width(std::max(params.bounds.width(), 1)); + allocation_.set_height(std::max(params.bounds.height(), 1)); + + egl_window_ = wl_egl_window_create(wayland_window_->surface(), + allocation_.width(), + allocation_.height(), + wayland_display_->visual()); + + SetNativeWindowProperty(kNativeWidgetKey, this); + + if (View::get_use_acceleration_when_possible()) { + if (Widget::compositor_factory()) { + compositor_ = (*Widget::compositor_factory())(); + } else { + compositor_ = ui::Compositor::Create(egl_window_, allocation_.size()); + } + if (compositor_.get()) + delegate_->AsWidget()->GetRootView()->SetPaintToLayer(true); + } else { + surface_ = gfx::GLSurface::CreateViewGLSurface(false, egl_window_); + context_ = gfx::GLContext::CreateGLContext(NULL, surface_.get()); + + if (!context_->MakeCurrent(surface_.get())) + DLOG(ERROR) << "Failed to make surface current"; + + device_ = cairo_egl_device_create(gfx::GLSurfaceEGL::GetHardwareDisplay(), + context_->GetHandle()); + if (cairo_device_status(device_) != CAIRO_STATUS_SUCCESS) + DLOG(ERROR) << "Failed to create cairo egl device"; + + cairo_surface_ = cairo_gl_surface_create_for_egl(device_, + surface_->GetHandle(), + allocation_.width(), + allocation_.height()); + cairo_surface_set_user_data(cairo_surface_, + &surface_data_key_, + this, + NULL); + } + + delegate_->OnNativeWidgetCreated(); + + if (params.type != Widget::InitParams::TYPE_TOOLTIP) { + // TODO(dnicoara) Enable this once it works with Wayland + /* + views::TooltipManagerViews* manager = new views::TooltipManagerViews( + static_cast<internal::RootView*>(GetWidget()->GetRootView())); + tooltip_manager_.reset(manager); + */ + } + + // TODO(dnicoara) This should be removed when we can specify the (x, y) + // coordinates for a window. We use fullscreen since it will center the + // window rather than give it random (x, y) coordinates. + wayland_window_->set_fullscreen(true); + Show(); + OnPaint(allocation_); +} + +NonClientFrameView* NativeWidgetWayland::CreateNonClientFrameView() { + return NULL; +} + +void NativeWidgetWayland::UpdateFrameAfterFrameChange() { + NOTIMPLEMENTED(); +} + +bool NativeWidgetWayland::ShouldUseNativeFrame() const { + NOTIMPLEMENTED(); + return false; +} + +void NativeWidgetWayland::FrameTypeChanged() { + // Called when the Theme has changed, so forward the event to the root + // widget + GetWidget()->ThemeChanged(); + GetWidget()->GetRootView()->SchedulePaint(); +} + +Widget* NativeWidgetWayland::GetWidget() { + return delegate_->AsWidget(); +} + +const Widget* NativeWidgetWayland::GetWidget() const { + return delegate_->AsWidget(); +} + +gfx::NativeView NativeWidgetWayland::GetNativeView() const { + return wayland_window_; +} + +gfx::NativeWindow NativeWidgetWayland::GetNativeWindow() const { + return wayland_window_; +} + +Widget* NativeWidgetWayland::GetTopLevelWidget() { + NativeWidgetPrivate* native_widget = GetTopLevelNativeWidget(GetNativeView()); + return native_widget ? native_widget->GetWidget() : NULL; +} + +const ui::Compositor* NativeWidgetWayland::GetCompositor() const { + return compositor_.get(); +} + +ui::Compositor* NativeWidgetWayland::GetCompositor() { + return compositor_.get(); +} + +void NativeWidgetWayland::MarkLayerDirty() { +} + +void NativeWidgetWayland::CalculateOffsetToAncestorWithLayer( + gfx::Point* offset, + View** ancestor) { +} + +void NativeWidgetWayland::ViewRemoved(View* view) { + NOTIMPLEMENTED(); +} + +void NativeWidgetWayland::SetNativeWindowProperty(const char* name, + void* value) { + // Remove the existing property (if any). + for (ViewProps::iterator i = props_.begin(); i != props_.end(); ++i) { + if ((*i)->Key() == name) { + props_.erase(i); + break; + } + } + + if (value) + props_.push_back(new ViewProp(wayland_window_, name, value)); +} + +void* NativeWidgetWayland::GetNativeWindowProperty(const char* name) const { + return ViewProp::GetValue(wayland_window_, name); +} + +TooltipManager* NativeWidgetWayland::GetTooltipManager() const { + return tooltip_manager_.get(); +} + +bool NativeWidgetWayland::IsScreenReaderActive() const { + return false; +} + +void NativeWidgetWayland::SendNativeAccessibilityEvent( + View* view, + ui::AccessibilityTypes::Event event_type) { + NOTIMPLEMENTED(); +} + +void NativeWidgetWayland::SetMouseCapture() { + NOTIMPLEMENTED(); + has_mouse_capture_ = true; +} + +void NativeWidgetWayland::ReleaseMouseCapture() { + NOTIMPLEMENTED(); + has_mouse_capture_ = false; +} + +bool NativeWidgetWayland::HasMouseCapture() const { + NOTIMPLEMENTED(); + return has_mouse_capture_; +} + +InputMethod* NativeWidgetWayland::CreateInputMethod() { + return new InputMethodWayland(this); +} + +void NativeWidgetWayland::CenterWindow(const gfx::Size& size) { + NOTIMPLEMENTED(); +} + +void NativeWidgetWayland::GetWindowBoundsAndMaximizedState( + gfx::Rect* bounds, + bool* maximized) const { + NOTIMPLEMENTED(); +} + +void NativeWidgetWayland::SetWindowTitle(const std::wstring& title) { +} + +void NativeWidgetWayland::SetWindowIcons(const SkBitmap& window_icon, + const SkBitmap& app_icon) { +} + +void NativeWidgetWayland::SetAccessibleName(const std::wstring& name) { +} + +void NativeWidgetWayland::SetAccessibleRole( + ui::AccessibilityTypes::Role role) { +} + +void NativeWidgetWayland::SetAccessibleState( + ui::AccessibilityTypes::State state) { +} + +void NativeWidgetWayland::BecomeModal() { + NOTIMPLEMENTED(); +} + +gfx::Rect NativeWidgetWayland::GetWindowScreenBounds() const { + return GetClientAreaScreenBounds(); +} + +gfx::Rect NativeWidgetWayland::GetClientAreaScreenBounds() const { + return allocation_; +} + +gfx::Rect NativeWidgetWayland::GetRestoredBounds() const { + return GetWindowScreenBounds(); +} + +void NativeWidgetWayland::SetBounds(const gfx::Rect& bounds) { + saved_allocation_ = allocation_; + allocation_ = bounds; + + // TODO(dnicoara) This needs to be updated to include (x, y). + wl_egl_window_resize(egl_window_, + allocation_.width(), + allocation_.height(), + 0, 0); + if (!View::get_use_acceleration_when_possible()) { + cairo_gl_surface_set_size(cairo_surface_, + allocation_.width(), + allocation_.height()); + } + + if (compositor_.get()) + compositor_->WidgetSizeChanged(allocation_.size()); + delegate_->OnNativeWidgetSizeChanged(allocation_.size()); +} + +void NativeWidgetWayland::SetSize(const gfx::Size& size) { + gfx::Rect new_alloc = allocation_; + new_alloc.set_size(size); + + SetBounds(new_alloc); +} + +void NativeWidgetWayland::SetBoundsConstrained(const gfx::Rect& bounds, + Widget* other_widget) { + // TODO(dnicoara) Need to take into account |other_widget|. + SetBounds(bounds); +} + +void NativeWidgetWayland::MoveAbove(gfx::NativeView native_view) { + NOTIMPLEMENTED(); +} + +void NativeWidgetWayland::MoveToTop() { + NOTIMPLEMENTED(); +} + +void NativeWidgetWayland::SetShape(gfx::NativeRegion shape) { + NOTIMPLEMENTED(); +} + +void NativeWidgetWayland::Close() { + Hide(); + if (close_widget_factory_.empty()) { + MessageLoop::current()->PostTask(FROM_HERE, + close_widget_factory_.NewRunnableMethod( + &NativeWidgetWayland::CloseNow)); + } +} + +void NativeWidgetWayland::CloseNow() { + delegate_->OnNativeWidgetDestroying(); + delegate_->OnNativeWidgetDestroyed(); + if (ownership_ == Widget::InitParams::NATIVE_WIDGET_OWNS_WIDGET) + delete this; +} + +void NativeWidgetWayland::EnableClose(bool enable) { + NOTIMPLEMENTED(); +} + +void NativeWidgetWayland::Show() { + wayland_window_->SetVisible(true); + delegate_->OnNativeWidgetVisibilityChanged(true); +} + +void NativeWidgetWayland::Hide() { + wayland_window_->SetVisible(false); + delegate_->OnNativeWidgetVisibilityChanged(false); +} + +void NativeWidgetWayland::ShowMaximizedWithBounds( + const gfx::Rect& restored_bounds) { + Show(); + Maximize(); + saved_allocation_ = restored_bounds; +} + +void NativeWidgetWayland::ShowWithState(ShowState state) { + NOTIMPLEMENTED(); +} + +bool NativeWidgetWayland::IsVisible() const { + return wayland_window_->IsVisible(); +} + +void NativeWidgetWayland::Activate() { + NOTIMPLEMENTED(); +} + +void NativeWidgetWayland::Deactivate() { + NOTIMPLEMENTED(); +} + +bool NativeWidgetWayland::IsActive() const { + NOTIMPLEMENTED(); + return true; +} + +void NativeWidgetWayland::SetAlwaysOnTop(bool always_on_top) { + NOTIMPLEMENTED(); +} + +void NativeWidgetWayland::Maximize() { + std::list<ui::WaylandScreen*> screens = wayland_display_->GetScreenList(); + + if (screens.empty()) + return; + + // TODO(dnicoara) We need to intersect the current coordinates with the + // screen ones and decide the correct screen to fullscreen on. + ui::WaylandScreen* screen = screens.front(); + + SetBounds(screen->GetAllocation()); +} + +void NativeWidgetWayland::Minimize() { + NOTIMPLEMENTED(); +} + +bool NativeWidgetWayland::IsMaximized() const { + NOTIMPLEMENTED(); + return true; +} + +bool NativeWidgetWayland::IsMinimized() const { + NOTIMPLEMENTED(); + return false; +} + +void NativeWidgetWayland::Restore() { + NOTIMPLEMENTED(); +} + +void NativeWidgetWayland::SetFullscreen(bool fullscreen) { + gfx::Rect new_allocation = allocation_; + + if (fullscreen) { + std::list<ui::WaylandScreen*> screens = wayland_display_->GetScreenList(); + + if (screens.empty()) + return; + + // TODO(dnicoara) What does it mean to be fullscreen when having multiple + // monitors? If we're going fullscreen only on one screen then we need to + // intersect the current coordinates with the screen ones and decide the + // correct screen to fullscreen on. + ui::WaylandScreen* screen = screens.front(); + new_allocation = screen->GetAllocation(); + } else { + new_allocation = saved_allocation_; + } + + wayland_window_->set_fullscreen(fullscreen); + SetBounds(new_allocation); +} + +bool NativeWidgetWayland::IsFullscreen() const { + return wayland_window_->fullscreen(); +} + +void NativeWidgetWayland::SetOpacity(unsigned char opacity) { + NOTIMPLEMENTED(); +} + +void NativeWidgetWayland::SetUseDragFrame(bool use_drag_frame) { + NOTIMPLEMENTED(); +} + +bool NativeWidgetWayland::IsAccessibleWidget() const { + NOTIMPLEMENTED(); + return true; +} + +void NativeWidgetWayland::RunShellDrag(View* view, + const ui::OSExchangeData& data, + int operation) { + NOTIMPLEMENTED(); +} + +gboolean NativeWidgetWayland::IdleRedraw(void* ptr) { + NativeWidgetWayland* widget = static_cast<NativeWidgetWayland*>(ptr); + gfx::Rect damage_area = widget->damage_area_; + widget->damage_area_ = gfx::Rect(); + + widget->OnPaint(damage_area); + + return FALSE; +} + +void NativeWidgetWayland::SchedulePaintInRect(const gfx::Rect& rect) { + if (damage_area_.IsEmpty()) + g_idle_add(NativeWidgetWayland::IdleRedraw, this); + + damage_area_ = damage_area_.Union(rect); +} + +void NativeWidgetWayland::SetCursor(gfx::NativeCursor cursor) { + NOTIMPLEMENTED(); +} + + +void NativeWidgetWayland::ClearNativeFocus() { + NOTIMPLEMENTED(); +} + + +void NativeWidgetWayland::FocusNativeView(gfx::NativeView native_view) { + NOTIMPLEMENTED(); +} + +bool NativeWidgetWayland::ConvertPointFromAncestor( + const Widget* ancestor, gfx::Point* point) const { + NOTREACHED(); + return false; +} + +// Overridden from NativeWidget +gfx::AcceleratedWidget NativeWidgetWayland::GetAcceleratedWidget() { + return egl_window_; +} + + +// Overridden from internal::InputMethodDelegate +void NativeWidgetWayland::DispatchKeyEventPostIME(const KeyEvent& key) { + NOTIMPLEMENTED(); + delegate_->OnKeyEvent(key); +} + +///////////////////////////////////////////////////////////////////////////// +// NativeWidgetWayland, private, event handlers + +void NativeWidgetWayland::OnPaint(gfx::Rect damage_area) { + if (!delegate_->OnNativeWidgetPaintAccelerated(damage_area)) { + // This is required since the CanvasSkiaPaint damages the surface + // in the destructor so we need to have this done before calling + // swapbuffers. + { + cairo_rectangle_int_t region = damage_area.ToCairoRectangle(); + gfx::CanvasSkiaPaint canvas(cairo_surface_, ®ion); + if (!canvas.is_empty()) { + canvas.set_composite_alpha(false); + delegate_->OnNativeWidgetPaint(&canvas); + } + } + + // Have cairo swap buffers, then let Wayland know of the damaged area. + cairo_gl_surface_swapbuffers(cairo_surface_); + wl_surface_damage(wayland_window_->surface(), + damage_area.x(), damage_area.y(), + damage_area.width(), damage_area.height()); + } +} + +void NativeWidgetWayland::OnMotionNotify(ui::WaylandEvent event) { + MouseEvent mouse_event(&event); + delegate_->OnMouseEvent(mouse_event); +} + +void NativeWidgetWayland::OnButtonNotify(ui::WaylandEvent event) { + if (event.button.button == ui::SCROLL_UP || + event.button.button == ui::SCROLL_DOWN) { + MouseWheelEvent mouse_event(&event); + delegate_->OnMouseEvent(mouse_event); + } else { + MouseEvent mouse_event(&event); + delegate_->OnMouseEvent(mouse_event); + } +} + +void NativeWidgetWayland::OnKeyNotify(ui::WaylandEvent event) { + KeyEvent key_event(&event); + InputMethod* input_method = GetWidget()->GetInputMethodDirect(); + if (input_method) + input_method->DispatchKeyEvent(key_event); + else + DispatchKeyEventPostIME(key_event); +} + +void NativeWidgetWayland::OnPointerFocus(ui::WaylandEvent event) { + MouseEvent mouse_event(&event); + delegate_->OnMouseEvent(mouse_event); +} + +void NativeWidgetWayland::OnKeyboardFocus(ui::WaylandEvent event) { + InputMethod* input_method = GetWidget()->GetInputMethodDirect(); + if (input_method) { + if (event.keyboard_focus.state) + input_method->OnFocus(); + else + input_method->OnBlur(); + } +} + +void NativeWidgetWayland::OnGeometryChange(ui::WaylandEvent event) { + SetSize(gfx::Size(event.geometry_change.width, + event.geometry_change.height)); +} + +///////////////////////////////////////////////////////////////////////////// +// Widget + +// static +bool Widget::ConvertRect(const Widget* source, + const Widget* target, + gfx::Rect* rect) { + DCHECK(source); + DCHECK(target); + DCHECK(rect); + + gfx::NativeView source_widget = source->GetNativeView(); + gfx::NativeView target_widget = target->GetNativeView(); + if (source_widget == target_widget) + return true; + + if (!source_widget || !target_widget) + return false; + + NOTIMPLEMENTED(); + return false; +} + +namespace internal { + +///////////////////////////////////////////////////////////////////////////// +// NativeWidget + +// static +NativeWidgetPrivate* NativeWidgetPrivate::CreateNativeWidget( + internal::NativeWidgetDelegate* delegate) { + if (Widget::IsPureViews() && + ViewsDelegate::views_delegate->GetDefaultParentView()) { + return new NativeWidgetViews(delegate); + } + return new NativeWidgetWayland(delegate); +} + +// static +NativeWidgetPrivate* NativeWidgetPrivate::GetNativeWidgetForNativeView( + gfx::NativeView native_view) { + return reinterpret_cast<NativeWidgetWayland*>( + ViewProp::GetValue(native_view, kNativeWidgetKey)); +} + +// static +NativeWidgetPrivate* NativeWidgetPrivate::GetNativeWidgetForNativeWindow( + gfx::NativeWindow native_window) { + return GetNativeWidgetForNativeView(native_window); +} + +// static +NativeWidgetPrivate* NativeWidgetPrivate::GetTopLevelNativeWidget( + gfx::NativeView native_view) { + // TODO(dnicoara) What would be the best way to implement this? + // Since there isn't any actual parenting concept in Wayland, we could + // implement it using WaylandWindow->SetParent/GetParent calls. + return GetNativeWidgetForNativeView(native_view); +} + +// static +void NativeWidgetPrivate::GetAllChildWidgets(gfx::NativeView native_view, + Widget::Widgets* children) { + NOTIMPLEMENTED(); + if (!native_view) + return; +} + +// static +void NativeWidgetPrivate::ReparentNativeView(gfx::NativeView native_view, + gfx::NativeView new_parent) { + NOTIMPLEMENTED(); + if (!native_view) + return; +} + +// static +bool NativeWidgetPrivate::IsMouseButtonDown() { + NOTIMPLEMENTED(); + return false; +} + +} // namespace internal + +} // namespace views diff --git a/views/widget/native_widget_wayland.h b/views/widget/native_widget_wayland.h new file mode 100644 index 0000000..fd2b0e3 --- /dev/null +++ b/views/widget/native_widget_wayland.h @@ -0,0 +1,204 @@ +// Copyright (c) 2011 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 VIEWS_WIDGET_NATIVE_WIDGET_WAYLAND_H_ +#define VIEWS_WIDGET_NATIVE_WIDGET_WAYLAND_H_ +#pragma once + +#include <wayland-client.h> + +#include "base/memory/scoped_vector.h" +#include "ui/gfx/gl/gl_context.h" +#include "ui/gfx/gl/gl_surface.h" +#include "ui/gfx/size.h" +#include "ui/wayland/wayland_widget.h" +#include "views/widget/native_widget_private.h" +#include "views/widget/widget.h" + +typedef struct _cairo_device cairo_device_t; +typedef struct _cairo_surface cairo_surface_t; + +namespace gfx { +class Rect; +} + +namespace ui { +class ViewProp; +class WaylandDisplay; +class WaylandInputDevice; +class WaylandWindow; +} + +namespace views { + +namespace internal { +class NativeWidgetDelegate; +} + +// Widget implementation for Wayland +class NativeWidgetWayland : public internal::NativeWidgetPrivate, + public ui::WaylandWidget { + public: + explicit NativeWidgetWayland(internal::NativeWidgetDelegate* delegate); + virtual ~NativeWidgetWayland(); + + // Overridden from NativeWidget: + virtual void InitNativeWidget(const Widget::InitParams& params) OVERRIDE; + virtual NonClientFrameView* CreateNonClientFrameView() OVERRIDE; + virtual void UpdateFrameAfterFrameChange() OVERRIDE; + virtual bool ShouldUseNativeFrame() const OVERRIDE; + virtual void FrameTypeChanged() OVERRIDE; + virtual Widget* GetWidget() OVERRIDE; + virtual const Widget* GetWidget() const OVERRIDE; + virtual gfx::NativeView GetNativeView() const OVERRIDE; + virtual gfx::NativeWindow GetNativeWindow() const OVERRIDE; + virtual Widget* GetTopLevelWidget() OVERRIDE; + virtual const ui::Compositor* GetCompositor() const OVERRIDE; + virtual ui::Compositor* GetCompositor() OVERRIDE; + virtual void MarkLayerDirty() OVERRIDE; + virtual void CalculateOffsetToAncestorWithLayer(gfx::Point* offset, + View** ancestor) OVERRIDE; + virtual void ViewRemoved(View* view) OVERRIDE; + virtual void SetNativeWindowProperty(const char* name, void* value) OVERRIDE; + virtual void* GetNativeWindowProperty(const char* name) const OVERRIDE; + virtual TooltipManager* GetTooltipManager() const OVERRIDE; + virtual bool IsScreenReaderActive() const OVERRIDE; + virtual void SendNativeAccessibilityEvent( + View* view, + ui::AccessibilityTypes::Event event_type) OVERRIDE; + virtual void SetMouseCapture() OVERRIDE; + virtual void ReleaseMouseCapture() OVERRIDE; + virtual bool HasMouseCapture() const OVERRIDE; + virtual InputMethod* CreateInputMethod() OVERRIDE; + virtual void CenterWindow(const gfx::Size& size) OVERRIDE; + virtual void GetWindowBoundsAndMaximizedState(gfx::Rect* bounds, + bool* maximized) const OVERRIDE; + virtual void SetWindowTitle(const std::wstring& title) OVERRIDE; + virtual void SetWindowIcons(const SkBitmap& window_icon, + const SkBitmap& app_icon) OVERRIDE; + virtual void SetAccessibleName(const std::wstring& name) OVERRIDE; + virtual void SetAccessibleRole(ui::AccessibilityTypes::Role role) OVERRIDE; + virtual void SetAccessibleState(ui::AccessibilityTypes::State state) OVERRIDE; + virtual void BecomeModal() OVERRIDE; + virtual gfx::Rect GetWindowScreenBounds() const OVERRIDE; + virtual gfx::Rect GetClientAreaScreenBounds() const OVERRIDE; + virtual gfx::Rect GetRestoredBounds() const OVERRIDE; + virtual void SetBounds(const gfx::Rect& bounds) OVERRIDE; + virtual void SetSize(const gfx::Size& size) OVERRIDE; + virtual void SetBoundsConstrained(const gfx::Rect& bounds, + Widget* other_widget) OVERRIDE; + virtual void MoveAbove(gfx::NativeView native_view) OVERRIDE; + virtual void MoveToTop() OVERRIDE; + virtual void SetShape(gfx::NativeRegion shape) OVERRIDE; + virtual void Close() OVERRIDE; + virtual void CloseNow() OVERRIDE; + virtual void EnableClose(bool enable) OVERRIDE; + virtual void Show() OVERRIDE; + virtual void Hide() OVERRIDE; + virtual void ShowMaximizedWithBounds( + const gfx::Rect& restored_bounds) OVERRIDE; + virtual void ShowWithState(ShowState state) OVERRIDE; + virtual bool IsVisible() const OVERRIDE; + virtual void Activate() OVERRIDE; + virtual void Deactivate() OVERRIDE; + virtual bool IsActive() const OVERRIDE; + virtual void SetAlwaysOnTop(bool always_on_top) OVERRIDE; + virtual void Maximize() OVERRIDE; + virtual void Minimize() OVERRIDE; + virtual bool IsMaximized() const OVERRIDE; + virtual bool IsMinimized() const OVERRIDE; + virtual void Restore() OVERRIDE; + virtual void SetFullscreen(bool fullscreen) OVERRIDE; + virtual bool IsFullscreen() const OVERRIDE; + virtual void SetOpacity(unsigned char opacity) OVERRIDE; + virtual void SetUseDragFrame(bool use_drag_frame) OVERRIDE; + virtual bool IsAccessibleWidget() const OVERRIDE; + virtual void RunShellDrag(View* view, + const ui::OSExchangeData& data, + int operation) OVERRIDE; + virtual void SchedulePaintInRect(const gfx::Rect& rect) OVERRIDE; + virtual void SetCursor(gfx::NativeCursor cursor) OVERRIDE; + virtual void ClearNativeFocus() OVERRIDE; + virtual void FocusNativeView(gfx::NativeView native_view) OVERRIDE; + virtual bool ConvertPointFromAncestor( + const Widget* ancestor, gfx::Point* point) const OVERRIDE; + + virtual void OnMotionNotify(ui::WaylandEvent event) OVERRIDE; + virtual void OnButtonNotify(ui::WaylandEvent event) OVERRIDE; + virtual void OnKeyNotify(ui::WaylandEvent event) OVERRIDE; + virtual void OnPointerFocus(ui::WaylandEvent event) OVERRIDE; + virtual void OnKeyboardFocus(ui::WaylandEvent event) OVERRIDE; + + virtual void OnGeometryChange(ui::WaylandEvent event) OVERRIDE; + + private: + typedef ScopedVector<ui::ViewProp> ViewProps; + + // Overridden from NativeWidget + virtual gfx::AcceleratedWidget GetAcceleratedWidget() OVERRIDE; + + // Overridden from internal::InputMethodDelegate + virtual void DispatchKeyEventPostIME(const KeyEvent& key) OVERRIDE; + + void OnPaint(gfx::Rect damage_area); + + static gboolean IdleRedraw(void* ptr); + + // A delegate implementation that handles events received here. + // See class documentation for Widget in widget.h for a note about ownership. + internal::NativeWidgetDelegate* delegate_; + + scoped_ptr<TooltipManager> tooltip_manager_; + + // The following factory is used to delay destruction. + ScopedRunnableMethodFactory<NativeWidgetWayland> close_widget_factory_; + + // See class documentation for Widget in widget.h for a note about ownership. + Widget::InitParams::Ownership ownership_; + + // Keeps track of mause capture for this widget. + bool has_mouse_capture_; + + // Current window allocation + gfx::Rect allocation_; + // Previous allocation. Used to restore the size and location. + gfx::Rect saved_allocation_; + + // The compositor for accelerated drawing. + scoped_refptr<ui::Compositor> compositor_; + + ViewProps props_; + + // Pointer to the Wayland display. This object doesn't own the pointer. + ui::WaylandDisplay* wayland_display_; + + // Wayland window associated with this widget. + ui::WaylandWindow* wayland_window_; + + // The accelerated surface associated with a Wayland window. + struct wl_egl_window* egl_window_; + + cairo_device_t* device_; + + // Cairo surface associated with the Wayland accelerated surface. This is + // used when we're not using the accelerated painting path. + cairo_surface_t* cairo_surface_; + const cairo_user_data_key_t surface_data_key_; + + // Used to accumulate damaged area between repaints. + // Necessary since Wayland seems to expect at most one paint per frame. + gfx::Rect damage_area_; + + // The GL surface and context used to render when we're using unaccelerated + // rendering. If we're using accelerated rendering, we'll have a compositor + // and the compositor will have these, so we don't need to worry about them. + scoped_refptr<gfx::GLSurface> surface_; + scoped_refptr<gfx::GLContext> context_; + + DISALLOW_COPY_AND_ASSIGN(NativeWidgetWayland); +}; + +} // namespace views + +#endif // VIEWS_WIDGET_NATIVE_WIDGET_WAYLAND_H_ diff --git a/views/widget/tooltip_manager_views.cc b/views/widget/tooltip_manager_views.cc index 4c0a728..b952b09 100644 --- a/views/widget/tooltip_manager_views.cc +++ b/views/widget/tooltip_manager_views.cc @@ -21,6 +21,10 @@ #include "views/widget/native_widget.h" #include "views/widget/root_view.h" +#if defined(USE_WAYLAND) +#include "ui/wayland/events/wayland_event.h" +#endif + namespace { SkColor kTooltipBackground = 0xFF7F7F00; int kTooltipTimeoutMs = 500; @@ -100,6 +104,21 @@ void TooltipManagerViews::HideKeyboardTooltip() { NOTREACHED(); } +#if defined(USE_WAYLAND) +base::MessagePumpObserver::EventStatus TooltipManagerViews::WillProcessEvent( + ui::WaylandEvent* event) { + if (event->type == ui::WAYLAND_MOTION) { + if (tooltip_timer_.IsRunning()) + tooltip_timer_.Reset(); + curr_mouse_pos_.SetPoint(event->motion.x, event->motion.y); + + // If tooltip is visible, we may want to hide it. If it is not, we are ok. + if (tooltip_widget_->IsVisible()) + UpdateIfRequired(curr_mouse_pos_.x(), curr_mouse_pos_.y(), false); + } + return base::MessagePumpObserver::EVENT_CONTINUE; +} +#else base::MessagePumpObserver::EventStatus TooltipManagerViews::WillProcessXEvent( XEvent* xevent) { XGenericEventCookie* cookie = &xevent->xcookie; @@ -115,6 +134,7 @@ base::MessagePumpObserver::EventStatus TooltipManagerViews::WillProcessXEvent( } return base::MessagePumpObserver::EVENT_CONTINUE; } +#endif void TooltipManagerViews::TooltipTimerFired() { if (tooltip_widget_->IsVisible()) { diff --git a/views/widget/tooltip_manager_views.h b/views/widget/tooltip_manager_views.h index 8bffaed..648c7cb 100644 --- a/views/widget/tooltip_manager_views.h +++ b/views/widget/tooltip_manager_views.h @@ -7,7 +7,6 @@ #pragma once #include "base/message_loop.h" -#include "base/message_pump_x.h" #include "base/timer.h" #include "views/controls/label.h" #include "views/widget/native_widget.h" @@ -17,6 +16,9 @@ typedef union _GdkEvent GdkEvent; typedef union _XEvent XEvent; +namespace ui { +union WaylandEvent; +} namespace views { @@ -39,9 +41,14 @@ class TooltipManagerViews : public TooltipManager, virtual void ShowKeyboardTooltip(View* view) OVERRIDE; virtual void HideKeyboardTooltip() OVERRIDE; +#if defined(USE_WAYLAND) + virtual base::MessagePumpObserver::EventStatus WillProcessEvent( + ui::WaylandEvent* event) OVERRIDE; +#else // MessageLoopForUI::Observer virtual base::MessagePumpObserver::EventStatus WillProcessXEvent( XEvent* xevent) OVERRIDE; +#endif private: void TooltipTimerFired(); diff --git a/views/window/dialog_client_view.cc b/views/window/dialog_client_view.cc index 08c833b..562c8cc 100644 --- a/views/window/dialog_client_view.cc +++ b/views/window/dialog_client_view.cc @@ -312,6 +312,9 @@ const DialogClientView* DialogClientView::AsDialogClientView() const { void DialogClientView::OnPaint(gfx::Canvas* canvas) { #if defined(OS_WIN) FillViewWithSysColor(canvas, this, GetSysColor(COLOR_3DFACE)); +#elif defined(USE_WAYLAND) + SkColor sk_color = SkColorSetARGB(200, 255, 255, 255); + canvas->FillRectInt(sk_color, 0, 0, width(), height()); #else GtkWidget* widget = GetWidget()->GetNativeView(); if (GTK_IS_WINDOW(widget)) { |