Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(310)

Side by Side Diff: views/widget/native_widget_wayland.cc

Issue 8598024: Now that we are doing a hard-cut-over to Aura, remove a bunch of *Views based classes that are ob... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 9 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « views/widget/native_widget_wayland.h ('k') | views/widget/native_widget_win.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "views/widget/native_widget_wayland.h"
6
7 #include <EGL/egl.h>
8 #include <GL/gl.h>
9 #include <cairo-gl.h>
10 #include <cairo.h>
11 #include <wayland-egl.h>
12
13 #include <algorithm>
14 #include <list>
15
16 #include "base/bind.h"
17 #include "base/memory/scoped_ptr.h"
18 #include "base/wayland/wayland_event.h"
19 #include "ui/base/view_prop.h"
20 #include "ui/gfx/canvas_skia_paint.h"
21 #include "ui/gfx/compositor/compositor.h"
22 #include "ui/gfx/gl/gl_surface.h"
23 #include "ui/gfx/gl/gl_surface_egl.h"
24 #include "ui/views/ime/input_method_wayland.h"
25 #include "ui/wayland/wayland_display.h"
26 #include "ui/wayland/wayland_input_device.h"
27 #include "ui/wayland/wayland_screen.h"
28 #include "ui/wayland/wayland_window.h"
29 #include "views/views_delegate.h"
30 #include "views/widget/native_widget_views.h"
31 #include "views/widget/root_view.h"
32 #include "views/widget/tooltip_manager_views.h"
33
34 using ui::ViewProp;
35
36 using base::wayland::WaylandEvent;
37
38 namespace views {
39
40 namespace {
41
42 // Links the WaylandWidget to its NativeWidget.
43 const char* const kNativeWidgetKey = "__VIEWS_NATIVE_WIDGET__";
44
45 } // namespace
46
47 NativeWidgetWayland::NativeWidgetWayland(
48 internal::NativeWidgetDelegate* delegate)
49 : delegate_(delegate),
50 ALLOW_THIS_IN_INITIALIZER_LIST(close_widget_factory_(this)),
51 ownership_(Widget::InitParams::NATIVE_WIDGET_OWNS_WIDGET),
52 has_mouse_capture_(false),
53 wayland_display_(
54 ui:: WaylandDisplay::GetDisplay(gfx::GLSurfaceEGL::GetNativeDisplay())),
55 wayland_window_(new ui::WaylandWindow(this, wayland_display_)),
56 surface_data_key_(),
57 damage_area_() {
58 }
59
60 NativeWidgetWayland::~NativeWidgetWayland() {
61 if (ownership_ == Widget::InitParams::NATIVE_WIDGET_OWNS_WIDGET)
62 delete delegate_;
63
64 if (!View::get_use_acceleration_when_possible()) {
65 cairo_surface_destroy(cairo_surface_);
66 cairo_device_destroy(device_);
67 }
68
69 if (egl_window_)
70 wl_egl_window_destroy(egl_window_);
71
72 if (wayland_window_)
73 delete wayland_window_;
74 }
75
76 void NativeWidgetWayland::InitNativeWidget(const Widget::InitParams& params) {
77 // Cannot create a window with a size smaller than 1x1
78 allocation_.set_width(std::max(params.bounds.width(), 1));
79 allocation_.set_height(std::max(params.bounds.height(), 1));
80
81 egl_window_ = wl_egl_window_create(wayland_window_->surface(),
82 allocation_.width(),
83 allocation_.height());
84
85 SetNativeWindowProperty(kNativeWidgetKey, this);
86
87 if (View::get_use_acceleration_when_possible()) {
88 if (ui::Compositor::compositor_factory()) {
89 compositor_ = (*ui::Compositor::compositor_factory())(this);
90 } else {
91 compositor_ = ui::Compositor::Create(this,
92 egl_window_,
93 allocation_.size());
94 }
95 if (compositor_.get())
96 delegate_->AsWidget()->GetRootView()->SetPaintToLayer(true);
97 } else {
98 surface_ = gfx::GLSurface::CreateViewGLSurface(false, egl_window_);
99 context_ = gfx::GLContext::CreateGLContext(
100 NULL,
101 surface_.get(),
102 gfx::PreferIntegratedGpu);
103
104 if (!context_->MakeCurrent(surface_.get()))
105 DLOG(ERROR) << "Failed to make surface current";
106
107 device_ = cairo_egl_device_create(gfx::GLSurfaceEGL::GetHardwareDisplay(),
108 context_->GetHandle());
109 if (cairo_device_status(device_) != CAIRO_STATUS_SUCCESS)
110 DLOG(ERROR) << "Failed to create cairo egl device";
111
112 cairo_surface_ = cairo_gl_surface_create_for_egl(device_,
113 surface_->GetHandle(),
114 allocation_.width(),
115 allocation_.height());
116 cairo_surface_set_user_data(cairo_surface_,
117 &surface_data_key_,
118 this,
119 NULL);
120 }
121
122 delegate_->OnNativeWidgetCreated();
123
124 if (params.type != Widget::InitParams::TYPE_TOOLTIP) {
125 // TODO(dnicoara) Enable this once it works with Wayland
126 /*
127 views::TooltipManagerViews* manager = new views::TooltipManagerViews(
128 static_cast<internal::RootView*>(GetWidget()->GetRootView()));
129 tooltip_manager_.reset(manager);
130 */
131 }
132
133 // TODO(dnicoara) This should be removed when we can specify the (x, y)
134 // coordinates for a window. We use fullscreen since it will center the
135 // window rather than give it random (x, y) coordinates.
136 wayland_window_->set_fullscreen(true);
137 Show();
138 OnPaint(allocation_);
139 }
140
141 NonClientFrameView* NativeWidgetWayland::CreateNonClientFrameView() {
142 return NULL;
143 }
144
145 void NativeWidgetWayland::UpdateFrameAfterFrameChange() {
146 NOTIMPLEMENTED();
147 }
148
149 bool NativeWidgetWayland::ShouldUseNativeFrame() const {
150 NOTIMPLEMENTED();
151 return false;
152 }
153
154 void NativeWidgetWayland::FrameTypeChanged() {
155 // Called when the Theme has changed, so forward the event to the root
156 // widget
157 GetWidget()->ThemeChanged();
158 GetWidget()->GetRootView()->SchedulePaint();
159 }
160
161 Widget* NativeWidgetWayland::GetWidget() {
162 return delegate_->AsWidget();
163 }
164
165 const Widget* NativeWidgetWayland::GetWidget() const {
166 return delegate_->AsWidget();
167 }
168
169 gfx::NativeView NativeWidgetWayland::GetNativeView() const {
170 return wayland_window_;
171 }
172
173 gfx::NativeWindow NativeWidgetWayland::GetNativeWindow() const {
174 return wayland_window_;
175 }
176
177 Widget* NativeWidgetWayland::GetTopLevelWidget() {
178 NativeWidgetPrivate* native_widget = GetTopLevelNativeWidget(GetNativeView());
179 return native_widget ? native_widget->GetWidget() : NULL;
180 }
181
182 const ui::Compositor* NativeWidgetWayland::GetCompositor() const {
183 return compositor_.get();
184 }
185
186 ui::Compositor* NativeWidgetWayland::GetCompositor() {
187 return compositor_.get();
188 }
189
190 void NativeWidgetWayland::CalculateOffsetToAncestorWithLayer(
191 gfx::Point* offset,
192 ui::Layer** layer_parent) {
193 }
194
195 void NativeWidgetWayland::ReorderLayers() {
196 }
197
198 void NativeWidgetWayland::ViewRemoved(View* view) {
199 NOTIMPLEMENTED();
200 }
201
202 void NativeWidgetWayland::SetNativeWindowProperty(const char* name,
203 void* value) {
204 // Remove the existing property (if any).
205 for (ViewProps::iterator i = props_.begin(); i != props_.end(); ++i) {
206 if ((*i)->Key() == name) {
207 props_.erase(i);
208 break;
209 }
210 }
211
212 if (value)
213 props_.push_back(new ViewProp(wayland_window_, name, value));
214 }
215
216 void* NativeWidgetWayland::GetNativeWindowProperty(const char* name) const {
217 return ViewProp::GetValue(wayland_window_, name);
218 }
219
220 TooltipManager* NativeWidgetWayland::GetTooltipManager() const {
221 return tooltip_manager_.get();
222 }
223
224 bool NativeWidgetWayland::IsScreenReaderActive() const {
225 return false;
226 }
227
228 void NativeWidgetWayland::SendNativeAccessibilityEvent(
229 View* view,
230 ui::AccessibilityTypes::Event event_type) {
231 NOTIMPLEMENTED();
232 }
233
234 void NativeWidgetWayland::SetMouseCapture() {
235 NOTIMPLEMENTED();
236 has_mouse_capture_ = true;
237 }
238
239 void NativeWidgetWayland::ReleaseMouseCapture() {
240 NOTIMPLEMENTED();
241 has_mouse_capture_ = false;
242 }
243
244 bool NativeWidgetWayland::HasMouseCapture() const {
245 NOTIMPLEMENTED();
246 return has_mouse_capture_;
247 }
248
249 InputMethod* NativeWidgetWayland::CreateInputMethod() {
250 return new InputMethodWayland(this);
251 }
252
253 void NativeWidgetWayland::CenterWindow(const gfx::Size& size) {
254 NOTIMPLEMENTED();
255 }
256
257 void NativeWidgetWayland::GetWindowPlacement(
258 gfx::Rect* bounds,
259 ui::WindowShowState* show_state) const {
260 NOTIMPLEMENTED();
261 }
262
263 void NativeWidgetWayland::SetWindowTitle(const string16& title) {
264 }
265
266 void NativeWidgetWayland::SetWindowIcons(const SkBitmap& window_icon,
267 const SkBitmap& app_icon) {
268 }
269
270 void NativeWidgetWayland::SetAccessibleName(const string16& name) {
271 }
272
273 void NativeWidgetWayland::SetAccessibleRole(
274 ui::AccessibilityTypes::Role role) {
275 }
276
277 void NativeWidgetWayland::SetAccessibleState(
278 ui::AccessibilityTypes::State state) {
279 }
280
281 void NativeWidgetWayland::BecomeModal() {
282 NOTIMPLEMENTED();
283 }
284
285 gfx::Rect NativeWidgetWayland::GetWindowScreenBounds() const {
286 return GetClientAreaScreenBounds();
287 }
288
289 gfx::Rect NativeWidgetWayland::GetClientAreaScreenBounds() const {
290 return allocation_;
291 }
292
293 gfx::Rect NativeWidgetWayland::GetRestoredBounds() const {
294 return GetWindowScreenBounds();
295 }
296
297 void NativeWidgetWayland::SetBounds(const gfx::Rect& bounds) {
298 saved_allocation_ = allocation_;
299 allocation_ = bounds;
300
301 // TODO(dnicoara) This needs to be updated to include (x, y).
302 wl_egl_window_resize(egl_window_,
303 allocation_.width(),
304 allocation_.height(),
305 0, 0);
306 if (!View::get_use_acceleration_when_possible()) {
307 cairo_gl_surface_set_size(cairo_surface_,
308 allocation_.width(),
309 allocation_.height());
310 }
311
312 if (compositor_.get())
313 compositor_->WidgetSizeChanged(allocation_.size());
314 delegate_->OnNativeWidgetSizeChanged(allocation_.size());
315 }
316
317 void NativeWidgetWayland::SetSize(const gfx::Size& size) {
318 gfx::Rect new_alloc = allocation_;
319 new_alloc.set_size(size);
320
321 SetBounds(new_alloc);
322 }
323
324 void NativeWidgetWayland::MoveAbove(gfx::NativeView native_view) {
325 NOTIMPLEMENTED();
326 }
327
328 void NativeWidgetWayland::MoveToTop() {
329 NOTIMPLEMENTED();
330 }
331
332 void NativeWidgetWayland::SetShape(gfx::NativeRegion shape) {
333 NOTIMPLEMENTED();
334 }
335
336 void NativeWidgetWayland::Close() {
337 Hide();
338 if (!close_widget_factory_.HasWeakPtrs()) {
339 MessageLoop::current()->PostTask(
340 FROM_HERE,
341 base::Bind(&NativeWidgetWayland::CloseNow,
342 close_widget_factory_.GetWeakPtr()));
343 }
344 }
345
346 void NativeWidgetWayland::CloseNow() {
347 delegate_->OnNativeWidgetDestroying();
348 delegate_->OnNativeWidgetDestroyed();
349 if (ownership_ == Widget::InitParams::NATIVE_WIDGET_OWNS_WIDGET)
350 delete this;
351 }
352
353 void NativeWidgetWayland::EnableClose(bool enable) {
354 NOTIMPLEMENTED();
355 }
356
357 void NativeWidgetWayland::Show() {
358 wayland_window_->SetVisible(true);
359 delegate_->OnNativeWidgetVisibilityChanged(true);
360 }
361
362 void NativeWidgetWayland::Hide() {
363 wayland_window_->SetVisible(false);
364 delegate_->OnNativeWidgetVisibilityChanged(false);
365 }
366
367 void NativeWidgetWayland::ShowMaximizedWithBounds(
368 const gfx::Rect& restored_bounds) {
369 Show();
370 Maximize();
371 saved_allocation_ = restored_bounds;
372 }
373
374 void NativeWidgetWayland::ShowWithWindowState(ui::WindowShowState state) {
375 NOTIMPLEMENTED();
376 }
377
378 bool NativeWidgetWayland::IsVisible() const {
379 return wayland_window_->IsVisible();
380 }
381
382 void NativeWidgetWayland::Activate() {
383 NOTIMPLEMENTED();
384 }
385
386 void NativeWidgetWayland::Deactivate() {
387 NOTIMPLEMENTED();
388 }
389
390 bool NativeWidgetWayland::IsActive() const {
391 NOTIMPLEMENTED();
392 return true;
393 }
394
395 void NativeWidgetWayland::SetAlwaysOnTop(bool always_on_top) {
396 NOTIMPLEMENTED();
397 }
398
399 void NativeWidgetWayland::Maximize() {
400 std::list<ui::WaylandScreen*> screens = wayland_display_->GetScreenList();
401
402 if (screens.empty())
403 return;
404
405 // TODO(dnicoara) We need to intersect the current coordinates with the
406 // screen ones and decide the correct screen to fullscreen on.
407 ui::WaylandScreen* screen = screens.front();
408
409 SetBounds(screen->GetAllocation());
410 }
411
412 void NativeWidgetWayland::Minimize() {
413 NOTIMPLEMENTED();
414 }
415
416 bool NativeWidgetWayland::IsMaximized() const {
417 NOTIMPLEMENTED();
418 return true;
419 }
420
421 bool NativeWidgetWayland::IsMinimized() const {
422 NOTIMPLEMENTED();
423 return false;
424 }
425
426 void NativeWidgetWayland::Restore() {
427 NOTIMPLEMENTED();
428 }
429
430 void NativeWidgetWayland::SetFullscreen(bool fullscreen) {
431 gfx::Rect new_allocation = allocation_;
432
433 if (fullscreen) {
434 std::list<ui::WaylandScreen*> screens = wayland_display_->GetScreenList();
435
436 if (screens.empty())
437 return;
438
439 // TODO(dnicoara) What does it mean to be fullscreen when having multiple
440 // monitors? If we're going fullscreen only on one screen then we need to
441 // intersect the current coordinates with the screen ones and decide the
442 // correct screen to fullscreen on.
443 ui::WaylandScreen* screen = screens.front();
444 new_allocation = screen->GetAllocation();
445 } else {
446 new_allocation = saved_allocation_;
447 }
448
449 wayland_window_->set_fullscreen(fullscreen);
450 SetBounds(new_allocation);
451 }
452
453 bool NativeWidgetWayland::IsFullscreen() const {
454 return wayland_window_->fullscreen();
455 }
456
457 void NativeWidgetWayland::SetOpacity(unsigned char opacity) {
458 NOTIMPLEMENTED();
459 }
460
461 void NativeWidgetWayland::SetUseDragFrame(bool use_drag_frame) {
462 NOTIMPLEMENTED();
463 }
464
465 bool NativeWidgetWayland::IsAccessibleWidget() const {
466 NOTIMPLEMENTED();
467 return true;
468 }
469
470 void NativeWidgetWayland::RunShellDrag(View* view,
471 const ui::OSExchangeData& data,
472 int operation) {
473 NOTIMPLEMENTED();
474 }
475
476 gboolean NativeWidgetWayland::IdleRedraw(void* ptr) {
477 NativeWidgetWayland* widget = static_cast<NativeWidgetWayland*>(ptr);
478 gfx::Rect damage_area = widget->damage_area_;
479 widget->damage_area_ = gfx::Rect();
480
481 widget->OnPaint(damage_area);
482
483 return FALSE;
484 }
485
486 void NativeWidgetWayland::SchedulePaintInRect(const gfx::Rect& rect) {
487 if (damage_area_.IsEmpty())
488 g_idle_add(NativeWidgetWayland::IdleRedraw, this);
489
490 damage_area_ = damage_area_.Union(rect);
491 }
492
493 void NativeWidgetWayland::SetCursor(gfx::NativeCursor cursor) {
494 NOTIMPLEMENTED();
495 }
496
497
498 void NativeWidgetWayland::ClearNativeFocus() {
499 NOTIMPLEMENTED();
500 }
501
502
503 void NativeWidgetWayland::FocusNativeView(gfx::NativeView native_view) {
504 NOTIMPLEMENTED();
505 }
506
507 bool NativeWidgetWayland::ConvertPointFromAncestor(
508 const Widget* ancestor, gfx::Point* point) const {
509 NOTREACHED();
510 return false;
511 }
512
513 void NativeWidgetWayland::ScheduleDraw() {
514 SchedulePaintInRect(allocation_);
515 }
516
517 // Overridden from NativeWidget
518 gfx::AcceleratedWidget NativeWidgetWayland::GetAcceleratedWidget() {
519 return egl_window_;
520 }
521
522
523 // Overridden from internal::InputMethodDelegate
524 void NativeWidgetWayland::DispatchKeyEventPostIME(const KeyEvent& key) {
525 NOTIMPLEMENTED();
526 delegate_->OnKeyEvent(key);
527 }
528
529 /////////////////////////////////////////////////////////////////////////////
530 // NativeWidgetWayland, private, event handlers
531
532 void NativeWidgetWayland::OnPaint(gfx::Rect damage_area) {
533 if (!delegate_->OnNativeWidgetPaintAccelerated(damage_area)) {
534 // This is required since the CanvasSkiaPaint damages the surface
535 // in the destructor so we need to have this done before calling
536 // swapbuffers.
537 {
538 cairo_rectangle_int_t region = damage_area.ToCairoRectangle();
539 gfx::CanvasSkiaPaint canvas(cairo_surface_, &region);
540 if (!canvas.is_empty()) {
541 canvas.set_composite_alpha(false);
542 delegate_->OnNativeWidgetPaint(&canvas);
543 }
544 }
545
546 // Have cairo swap buffers, then let Wayland know of the damaged area.
547 cairo_gl_surface_swapbuffers(cairo_surface_);
548 wl_surface_damage(wayland_window_->surface(),
549 damage_area.x(), damage_area.y(),
550 damage_area.width(), damage_area.height());
551 }
552 }
553
554 void NativeWidgetWayland::OnMotionNotify(WaylandEvent event) {
555 MouseEvent mouse_event(&event);
556 delegate_->OnMouseEvent(mouse_event);
557 }
558
559 void NativeWidgetWayland::OnButtonNotify(WaylandEvent event) {
560 if (event.button.button == ui::SCROLL_UP ||
561 event.button.button == ui::SCROLL_DOWN) {
562 MouseWheelEvent mouse_event(&event);
563 delegate_->OnMouseEvent(mouse_event);
564 } else {
565 MouseEvent mouse_event(&event);
566 delegate_->OnMouseEvent(mouse_event);
567 }
568 }
569
570 void NativeWidgetWayland::OnKeyNotify(WaylandEvent event) {
571 KeyEvent key_event(&event);
572 InputMethod* input_method = GetWidget()->GetInputMethodDirect();
573 if (input_method)
574 input_method->DispatchKeyEvent(key_event);
575 else
576 DispatchKeyEventPostIME(key_event);
577 }
578
579 void NativeWidgetWayland::OnPointerFocus(WaylandEvent event) {
580 MouseEvent mouse_event(&event);
581 delegate_->OnMouseEvent(mouse_event);
582 }
583
584 void NativeWidgetWayland::OnKeyboardFocus(WaylandEvent event) {
585 InputMethod* input_method = GetWidget()->GetInputMethodDirect();
586 if (input_method) {
587 if (event.keyboard_focus.state)
588 input_method->OnFocus();
589 else
590 input_method->OnBlur();
591 }
592 }
593
594 void NativeWidgetWayland::OnGeometryChange(WaylandEvent event) {
595 SetSize(gfx::Size(event.geometry_change.width,
596 event.geometry_change.height));
597 }
598
599 /////////////////////////////////////////////////////////////////////////////
600 // Widget
601
602 // static
603 bool Widget::ConvertRect(const Widget* source,
604 const Widget* target,
605 gfx::Rect* rect) {
606 DCHECK(source);
607 DCHECK(target);
608 DCHECK(rect);
609
610 gfx::NativeView source_widget = source->GetNativeView();
611 gfx::NativeView target_widget = target->GetNativeView();
612 if (source_widget == target_widget)
613 return true;
614
615 if (!source_widget || !target_widget)
616 return false;
617
618 NOTIMPLEMENTED();
619 return false;
620 }
621
622 namespace internal {
623
624 /////////////////////////////////////////////////////////////////////////////
625 // NativeWidget
626
627 // static
628 NativeWidgetPrivate* NativeWidgetPrivate::CreateNativeWidget(
629 internal::NativeWidgetDelegate* delegate) {
630 if (Widget::IsPureViews() &&
631 ViewsDelegate::views_delegate->GetDefaultParentView()) {
632 return new NativeWidgetViews(delegate);
633 }
634 return new NativeWidgetWayland(delegate);
635 }
636
637 // static
638 NativeWidgetPrivate* NativeWidgetPrivate::GetNativeWidgetForNativeView(
639 gfx::NativeView native_view) {
640 return reinterpret_cast<NativeWidgetWayland*>(
641 ViewProp::GetValue(native_view, kNativeWidgetKey));
642 }
643
644 // static
645 NativeWidgetPrivate* NativeWidgetPrivate::GetNativeWidgetForNativeWindow(
646 gfx::NativeWindow native_window) {
647 return GetNativeWidgetForNativeView(native_window);
648 }
649
650 // static
651 NativeWidgetPrivate* NativeWidgetPrivate::GetTopLevelNativeWidget(
652 gfx::NativeView native_view) {
653 // TODO(dnicoara) What would be the best way to implement this?
654 // Since there isn't any actual parenting concept in Wayland, we could
655 // implement it using WaylandWindow->SetParent/GetParent calls.
656 return GetNativeWidgetForNativeView(native_view);
657 }
658
659 // static
660 void NativeWidgetPrivate::GetAllChildWidgets(gfx::NativeView native_view,
661 Widget::Widgets* children) {
662 NOTIMPLEMENTED();
663 if (!native_view)
664 return;
665 }
666
667 // static
668 void NativeWidgetPrivate::ReparentNativeView(gfx::NativeView native_view,
669 gfx::NativeView new_parent) {
670 NOTIMPLEMENTED();
671 if (!native_view)
672 return;
673 }
674
675 // static
676 bool NativeWidgetPrivate::IsMouseButtonDown() {
677 NOTIMPLEMENTED();
678 return false;
679 }
680
681 } // namespace internal
682
683 } // namespace views
OLDNEW
« no previous file with comments | « views/widget/native_widget_wayland.h ('k') | views/widget/native_widget_win.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698