1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Copyright 2013 Intel Corporation. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
6 #include "ozone/ui/desktop_aura/desktop_window_tree_host_wayland.h"
10 #include "base/bind.h"
11 #include "base/strings/utf_string_conversions.h"
12 #include "ozone/ui/desktop_aura/desktop_drag_drop_client_wayland.h"
13 #include "ozone/ui/desktop_aura/desktop_screen_wayland.h"
14 #include "ozone/ui/desktop_aura/window_tree_host_delegate_wayland.h"
15 #include "ozone/ui/events/window_state_change_handler.h"
16 #include "ui/aura/client/cursor_client.h"
17 #include "ui/aura/client/focus_client.h"
18 #include "ui/aura/window_property.h"
19 #include "ui/base/dragdrop/os_exchange_data_provider_aura.h"
20 #include "ui/base/ime/composition_text.h"
21 #include "ui/base/ime/input_method.h"
22 #include "ui/base/ime/input_method_auralinux.h"
23 #include "ui/events/event_utils.h"
24 #include "ui/gfx/insets.h"
25 #include "ui/native_theme/native_theme.h"
26 #include "ui/ozone/public/ozone_platform.h"
27 #include "ui/ozone/public/surface_factory_ozone.h"
28 #include "ui/platform_window/platform_window.h"
29 #include "ui/platform_window/platform_window_delegate.h"
30 #include "ui/views/corewm/tooltip_aura.h"
31 #include "ui/views/ime/input_method.h"
32 #include "ui/views/linux_ui/linux_ui.h"
33 #include "ui/views/views_export.h"
34 #include "ui/views/widget/desktop_aura/desktop_dispatcher_client.h"
35 #include "ui/views/widget/desktop_aura/desktop_native_cursor_manager.h"
36 #include "ui/views/widget/desktop_aura/desktop_native_widget_aura.h"
37 #include "ui/views/widget/desktop_aura/desktop_screen_position_client.h"
38 #include "ui/wm/core/input_method_event_filter.h"
39 #include "ui/wm/core/window_util.h"
40 #include "ui/wm/public/window_move_client.h"
44 WindowTreeHostDelegateWayland*
45 DesktopWindowTreeHostWayland::g_delegate_ozone_wayland_ = NULL;
47 DEFINE_WINDOW_PROPERTY_KEY(
48 aura::Window*, kViewsWindowForRootWindow, NULL);
50 DEFINE_WINDOW_PROPERTY_KEY(
51 DesktopWindowTreeHostWayland*, kHostForRootWindow, NULL);
53 DesktopWindowTreeHostWayland::DesktopWindowTreeHostWayland(
54 internal::NativeWidgetDelegate* native_widget_delegate,
55 DesktopNativeWidgetAura* desktop_native_widget_aura)
56 : aura::WindowTreeHost(),
57 state_(Uninitialized),
59 previous_bounds_(0, 0, 0, 0),
60 previous_maximize_bounds_(0, 0, 0, 0),
62 title_(base::string16()),
63 close_widget_factory_(this),
64 drag_drop_client_(NULL),
65 native_widget_delegate_(native_widget_delegate),
66 content_window_(NULL),
67 desktop_native_widget_aura_(desktop_native_widget_aura),
72 DesktopWindowTreeHostWayland::~DesktopWindowTreeHostWayland() {
73 window()->ClearProperty(kHostForRootWindow);
74 aura::client::SetWindowMoveClient(window(), NULL);
75 desktop_native_widget_aura_->OnDesktopWindowTreeHostDestroyed(this);
80 DesktopWindowTreeHostWayland*
81 DesktopWindowTreeHostWayland::GetHostForAcceleratedWidget(
82 gfx::AcceleratedWidget widget) {
83 aura::WindowTreeHost* host =
84 aura::WindowTreeHost::GetForAcceleratedWidget(widget);
86 return host ? host->window()->GetProperty(kHostForRootWindow) : NULL;
90 const std::vector<aura::Window*>&
91 DesktopWindowTreeHostWayland::GetAllOpenWindows() {
92 DCHECK(g_delegate_ozone_wayland_);
93 return g_delegate_ozone_wayland_->GetAllOpenWindows();
98 DesktopWindowTreeHostWayland::GetContentWindowForAcceleratedWidget(
99 gfx::AcceleratedWidget widget) {
100 aura::WindowTreeHost* host =
101 aura::WindowTreeHost::GetForAcceleratedWidget(widget);
104 host->window()->GetProperty(kViewsWindowForRootWindow) : NULL;
107 gfx::Rect DesktopWindowTreeHostWayland::GetBoundsInScreen() const {
111 ////////////////////////////////////////////////////////////////////////////////
112 // DesktopWindowTreeHostWayland, private:
114 void DesktopWindowTreeHostWayland::InitWaylandWindow(
115 const Widget::InitParams& params) {
116 bounds_ = params.bounds;
118 ui::OzonePlatform::GetInstance()->CreatePlatformWindow(this, bounds_);
120 // Maintain parent child relation as done in X11 version.
121 // If we have a parent, record the parent/child relationship. We use this
122 // data during destruction to make sure that when we try to close a parent
123 // window, we also destroy all child windows.
124 if (params.parent && params.parent->GetHost()) {
125 gfx::AcceleratedWidget windowId = params.parent->GetHost()->
126 GetAcceleratedWidget();
127 window_parent_ = GetHostForAcceleratedWidget(windowId);
128 DCHECK(window_parent_);
129 window_parent_->window_children_.insert(this);
132 ui::WindowStateChangeHandler* state_handler =
133 ui::WindowStateChangeHandler::GetInstance();
134 switch (params.type) {
135 case Widget::InitParams::TYPE_TOOLTIP:
136 case Widget::InitParams::TYPE_POPUP:
137 case Widget::InitParams::TYPE_MENU: {
138 // Wayland surfaces don't know their position on the screen and transient
139 // surfaces always require a parent surface for relative placement. Here
140 // there's a catch because content_shell menus don't have parent and
141 // therefore we use root window to calculate their position.
142 DesktopWindowTreeHostWayland* parent = window_parent_;
144 parent = GetHostForAcceleratedWidget(
145 g_delegate_ozone_wayland_->GetActiveWindow()->window_);
147 // Transient type expects a position relative to the parent
148 gfx::Point transientPos(bounds_.x() - parent->bounds_.x(),
149 bounds_.y() - parent->bounds_.y());
151 // Different platforms implement different input grab pointer behaviors
152 // on Chromium. While the Linux GTK+ grab button clicks but not the
153 // pointer movement, the MS Windows implementation don't implement any
154 // pointer grab. In here we're using another different behavior for
155 // Chromium, but which is the common sense on most Wayland UI
156 // environments, where the input pointer is grabbed as a whole when a
157 // menu type of window is opened. I.e. both pointer clicks and movements
158 // will be routed only to the newly created window (grab installed). For
159 // more information please refer to the Wayland protocol.
160 state_handler->SetWidgetAttributes(window_,
167 case Widget::InitParams::TYPE_BUBBLE:
168 case Widget::InitParams::TYPE_WINDOW:
169 state_handler->SetWidgetAttributes(window_,
175 case Widget::InitParams::TYPE_WINDOW_FRAMELESS:
182 CreateCompositor(GetAcceleratedWidget());
185 void DesktopWindowTreeHostWayland::OnAcceleratedWidgetAvailable(
186 gfx::AcceleratedWidget widget) {
190 ////////////////////////////////////////////////////////////////////////////////
191 // DesktopWindowTreeHostWayland, DesktopWindowTreeHost implementation:
193 void DesktopWindowTreeHostWayland::Init(
194 aura::Window* content_window,
195 const Widget::InitParams& params) {
196 content_window_ = content_window;
197 // In some situations, views tries to make a zero sized window, and that
198 // makes us crash. Make sure we have valid sizes.
199 Widget::InitParams sanitized_params = params;
200 if (sanitized_params.bounds.width() == 0)
201 sanitized_params.bounds.set_width(100);
202 if (sanitized_params.bounds.height() == 0)
203 sanitized_params.bounds.set_height(100);
205 InitWaylandWindow(sanitized_params);
208 void DesktopWindowTreeHostWayland::OnNativeWidgetCreated(
209 const Widget::InitParams& params) {
210 window()->SetProperty(kViewsWindowForRootWindow, content_window_);
211 window()->SetProperty(kHostForRootWindow, this);
213 // If we're given a parent, we need to mark ourselves as transient to another
214 // window. Otherwise activation gets screwy.
215 gfx::NativeView parent = params.parent;
216 if (!params.child && params.parent)
217 wm::AddTransientChild(parent, content_window_);
219 native_widget_delegate_->OnNativeWidgetCreated(true);
221 if (!g_delegate_ozone_wayland_)
222 g_delegate_ozone_wayland_ = new WindowTreeHostDelegateWayland();
224 g_delegate_ozone_wayland_->OnRootWindowCreated(window_);
226 // Add DesktopWindowTreeHostWayland as dispatcher.
227 bool root_window = params.type == Widget::InitParams::TYPE_BUBBLE ||
228 params.type == Widget::InitParams::TYPE_WINDOW ||
229 params.type == Widget::InitParams::TYPE_WINDOW_FRAMELESS;
230 if (!window_parent_ && root_window)
231 g_delegate_ozone_wayland_->SetActiveWindow(this);
234 scoped_ptr<corewm::Tooltip>
235 DesktopWindowTreeHostWayland::CreateTooltip() {
236 return scoped_ptr<corewm::Tooltip>(
237 new corewm::TooltipAura(gfx::SCREEN_TYPE_NATIVE));
240 scoped_ptr<aura::client::DragDropClient>
241 DesktopWindowTreeHostWayland::CreateDragDropClient(
242 DesktopNativeCursorManager* cursor_manager) {
243 drag_drop_client_ = new DesktopDragDropClientWayland(window());
244 return scoped_ptr<aura::client::DragDropClient>(drag_drop_client_).Pass();
247 void DesktopWindowTreeHostWayland::Close() {
248 if (!close_widget_factory_.HasWeakPtrs()) {
249 // And we delay the close so that if we are called from an ATL callback,
250 // we don't destroy the window before the callback returned (as the caller
251 // may delete ourselves on destroy and the ATL callback would still
252 // dereference us when the callback returns).
253 base::MessageLoop::current()->PostTask(
255 base::Bind(&DesktopWindowTreeHostWayland::CloseNow,
256 close_widget_factory_.GetWeakPtr()));
260 void DesktopWindowTreeHostWayland::CloseNow() {
261 DCHECK(g_delegate_ozone_wayland_);
262 unsigned widgetId = window_;
263 native_widget_delegate_->OnNativeWidgetDestroying();
265 // If we have children, close them. Use a copy for iteration because they'll
266 // remove themselves.
267 std::set<DesktopWindowTreeHostWayland*> window_children_copy =
269 for (std::set<DesktopWindowTreeHostWayland*>::iterator it =
270 window_children_copy.begin(); it != window_children_copy.end();
274 DCHECK(window_children_.empty());
276 // If we have a parent, remove ourselves from its children list.
278 window_parent_->window_children_.erase(this);
280 g_delegate_ozone_wayland_->OnRootWindowClosed(widgetId);
281 // Destroy the compositor before destroying the window since shutdown
282 // may try to swap, and the swap without a window causes an error, which
283 // causes a crash with in-process renderer.
285 window_parent_ = NULL;
286 if (!g_delegate_ozone_wayland_->GetActiveWindow()) {
287 // We have no open windows, free g_delegate_ozone_wayland_.
288 delete g_delegate_ozone_wayland_;
289 g_delegate_ozone_wayland_ = NULL;
292 desktop_native_widget_aura_->OnHostClosed();
295 aura::WindowTreeHost* DesktopWindowTreeHostWayland::AsWindowTreeHost() {
299 void DesktopWindowTreeHostWayland::ShowWindowWithState(
300 ui::WindowShowState show_state) {
301 if (show_state != ui::SHOW_STATE_DEFAULT &&
302 show_state != ui::SHOW_STATE_NORMAL) {
303 // Only forwarding to Show().
308 if (show_state == ui::SHOW_STATE_MAXIMIZED)
311 // Set initial focus for root window.
313 native_widget_delegate_->AsWidget()->SetInitialFocus(show_state);
316 void DesktopWindowTreeHostWayland::ShowMaximizedWithBounds(
317 const gfx::Rect& restored_bounds) {
319 previous_bounds_ = restored_bounds;
323 bool DesktopWindowTreeHostWayland::IsVisible() const {
324 return state_ & Visible;
327 void DesktopWindowTreeHostWayland::SetSize(const gfx::Size& size) {
328 gfx::Rect new_bounds = bounds_;
329 new_bounds.set_size(size);
330 SetBounds(new_bounds);
333 void DesktopWindowTreeHostWayland::StackAtTop() {
336 void DesktopWindowTreeHostWayland::CenterWindow(const gfx::Size& size) {
337 gfx::Rect parent_bounds = GetWorkAreaBoundsInScreen();
339 // If |window_|'s transient parent bounds are big enough to contain |size|,
341 if (wm::GetTransientParent(content_window_)) {
342 gfx::Rect transient_parent_rect =
343 wm::GetTransientParent(content_window_)->GetBoundsInScreen();
344 if (transient_parent_rect.height() >= size.height() &&
345 transient_parent_rect.width() >= size.width()) {
346 parent_bounds = transient_parent_rect;
350 gfx::Rect window_bounds(
351 parent_bounds.x() + (parent_bounds.width() - size.width()) / 2,
352 parent_bounds.y() + (parent_bounds.height() - size.height()) / 2,
355 // Don't size the window bigger than the parent, otherwise the user may not be
356 // able to close or move it.
357 window_bounds.AdjustToFit(parent_bounds);
358 SetBounds(window_bounds);
361 void DesktopWindowTreeHostWayland::GetWindowPlacement(
363 ui::WindowShowState* show_state) const {
364 *bounds = GetRestoredBounds();
367 *show_state = ui::SHOW_STATE_MINIMIZED;
368 } else if (IsFullscreen()) {
369 *show_state = ui::SHOW_STATE_FULLSCREEN;
370 } else if (IsMaximized()) {
371 *show_state = ui::SHOW_STATE_MAXIMIZED;
372 } else if (!IsActive()) {
373 *show_state = ui::SHOW_STATE_INACTIVE;
375 *show_state = ui::SHOW_STATE_NORMAL;
379 gfx::Rect DesktopWindowTreeHostWayland::GetWindowBoundsInScreen() const {
383 gfx::Rect DesktopWindowTreeHostWayland::GetClientAreaBoundsInScreen() const {
384 // TODO(erg): The NativeWidgetAura version returns |bounds_|, claiming its
385 // needed for View::ConvertPointToScreen() to work
386 // correctly. DesktopWindowTreeHostWin::GetClientAreaBoundsInScreen() just
387 // asks windows what it thinks the client rect is.
389 // Attempts to calculate the rect by asking the NonClientFrameView what it
390 // thought its GetBoundsForClientView() were broke combobox drop down
395 gfx::Rect DesktopWindowTreeHostWayland::GetRestoredBounds() const {
396 if (!previous_bounds_.IsEmpty())
397 return previous_bounds_;
399 return GetWindowBoundsInScreen();
402 gfx::Rect DesktopWindowTreeHostWayland::GetWorkAreaBoundsInScreen() const {
403 // TODO(kalyan): Take into account wm decorations. i.e Dock, panel etc.
404 gfx::Screen *screen = gfx::Screen::GetScreenByType(gfx::SCREEN_TYPE_NATIVE);
406 NOTREACHED() << "Unable to retrieve valid gfx::Screen";
408 gfx::Display display = screen->GetPrimaryDisplay();
409 return display.bounds();
412 void DesktopWindowTreeHostWayland::SetShape(gfx::NativeRegion native_region) {
417 void DesktopWindowTreeHostWayland::Activate() {
422 if (state_ & Visible)
423 ui::WindowStateChangeHandler::GetInstance()->SetWidgetState(window_,
427 void DesktopWindowTreeHostWayland::Deactivate() {
428 if (!(state_ & Active))
432 ui::WindowStateChangeHandler::GetInstance()->SetWidgetState(window_,
436 bool DesktopWindowTreeHostWayland::IsActive() const {
437 return state_ & Active;
440 void DesktopWindowTreeHostWayland::Maximize() {
441 if (state_ & Maximized)
443 if (IsMinimized() && !window_parent_)
444 native_widget_delegate_->AsWidget()->SetInitialFocus(ui::SHOW_STATE_NORMAL);
447 state_ &= ~Minimized;
449 previous_bounds_ = bounds_;
450 ui::WindowStateChangeHandler::GetInstance()->SetWidgetState(window_,
454 void DesktopWindowTreeHostWayland::Minimize() {
455 if (state_ & Minimized)
459 previous_bounds_ = bounds_;
460 bounds_ = gfx::Rect();
461 ui::WindowStateChangeHandler::GetInstance()->SetWidgetState(window_,
463 OnHostResized(bounds_.size());
466 void DesktopWindowTreeHostWayland::Restore() {
470 if (IsMinimized() && !window_parent_)
471 native_widget_delegate_->AsWidget()->SetInitialFocus(ui::SHOW_STATE_NORMAL);
472 state_ &= ~Maximized;
473 state_ &= ~Minimized;
475 bounds_ = previous_bounds_;
476 previous_bounds_ = gfx::Rect();
477 ui::WindowStateChangeHandler::GetInstance()->SetWidgetState(
478 window_, ui::RESTORE, bounds_.width(), bounds_.height());
479 native_widget_delegate_->AsWidget()->OnNativeWidgetMove();
480 OnHostResized(bounds_.size());
483 bool DesktopWindowTreeHostWayland::IsMaximized() const {
484 return state_ & Maximized;
487 bool DesktopWindowTreeHostWayland::IsMinimized() const {
488 return state_ & Minimized;
491 void DesktopWindowTreeHostWayland::OnCaptureReleased() {
492 OnHostLostWindowCapture();
493 native_widget_delegate_->OnMouseCaptureLost();
496 bool DesktopWindowTreeHostWayland::HasCapture() const {
497 return g_delegate_ozone_wayland_->GetCurrentCapture() == this;
500 bool DesktopWindowTreeHostWayland::IsAlwaysOnTop() const {
505 void DesktopWindowTreeHostWayland::SetVisibleOnAllWorkspaces(
506 bool always_visible) {
510 void DesktopWindowTreeHostWayland::SetAlwaysOnTop(bool always_on_top) {
515 bool DesktopWindowTreeHostWayland::SetWindowTitle(const base::string16& title) {
516 if (title.compare(title_)) {
517 ui::WindowStateChangeHandler::GetInstance()->SetWidgetTitle(window_, title);
525 void DesktopWindowTreeHostWayland::ClearNativeFocus() {
526 // This method is weird and misnamed. Instead of clearing the native focus,
527 // it sets the focus to our |content_window_|, which will trigger a cascade
528 // of focus changes into views.
529 if (content_window_ && aura::client::GetFocusClient(content_window_) &&
530 content_window_->Contains(
531 aura::client::GetFocusClient(content_window_)->GetFocusedWindow())) {
532 aura::client::GetFocusClient(content_window_)->FocusWindow(content_window_);
536 Widget::MoveLoopResult DesktopWindowTreeHostWayland::RunMoveLoop(
537 const gfx::Vector2d& drag_offset,
538 Widget::MoveLoopSource source,
539 Widget::MoveLoopEscapeBehavior escape_behavior) {
541 return Widget::MOVE_LOOP_SUCCESSFUL;
544 void DesktopWindowTreeHostWayland::EndMoveLoop() {
548 void DesktopWindowTreeHostWayland::SetVisibilityChangedAnimationsEnabled(
550 // Much like the previous NativeWidgetGtk, we don't have anything to do here.
553 bool DesktopWindowTreeHostWayland::ShouldUseNativeFrame() const {
557 bool DesktopWindowTreeHostWayland::ShouldWindowContentsBeTransparent() const {
561 void DesktopWindowTreeHostWayland::FrameTypeChanged() {
562 Widget::FrameType new_type =
563 native_widget_delegate_->AsWidget()->frame_type();
564 if (new_type == Widget::FRAME_TYPE_DEFAULT) {
565 // The default is determined by Widget::InitParams::remove_standard_frame
566 // and does not change.
570 // Replace the frame and layout the contents. Even though we don't have a
571 // swapable glass frame like on Windows, we still replace the frame because
572 // the button assets don't update otherwise.
573 native_widget_delegate_->AsWidget()->non_client_view()->UpdateFrame();
576 void DesktopWindowTreeHostWayland::SetFullscreen(bool fullscreen) {
577 if ((state_ & FullScreen) == fullscreen)
581 state_ |= FullScreen;
584 state_ &= ~FullScreen;
587 if (!(state_ & FullScreen)) {
588 if (state_ & Maximized) {
589 previous_bounds_ = previous_maximize_bounds_;
590 previous_maximize_bounds_ = gfx::Rect();
591 ui::WindowStateChangeHandler::GetInstance()->SetWidgetState(
592 window_, ui::MAXIMIZED);
597 if (state_ & Maximized)
598 previous_maximize_bounds_ = previous_bounds_;
600 previous_bounds_ = bounds_;
601 gfx::Screen *screen = gfx::Screen::GetScreenByType(gfx::SCREEN_TYPE_NATIVE);
603 NOTREACHED() << "Unable to retrieve valid gfx::Screen";
605 bounds_ = screen->GetPrimaryDisplay().bounds();
606 // We could use HandleConfigure in ShellSurface to set the correct bounds of
607 // egl window associated with this opaque handle. How ever, this would need
608 // to handle race conditions and ensure correct size is set for
609 // wl_egl_window_resize before eglsurface is resized. Passing window size
610 // attributes already here, ensures that wl_egl_window_resize is resized
611 // before eglsurface is resized. This doesn't add any extra overhead as the
612 // IPC call needs to be done.
613 ui::WindowStateChangeHandler::GetInstance()->SetWidgetState(
614 window_, ui::FULLSCREEN, bounds_.width(), bounds_.height());
615 OnHostResized(bounds_.size());
619 bool DesktopWindowTreeHostWayland::IsFullscreen() const {
620 return state_ & FullScreen;
623 void DesktopWindowTreeHostWayland::SetOpacity(unsigned char opacity) {
628 void DesktopWindowTreeHostWayland::SetWindowIcons(
629 const gfx::ImageSkia& window_icon, const gfx::ImageSkia& app_icon) {
634 void DesktopWindowTreeHostWayland::InitModalType(ui::ModalType modal_type) {
635 switch (modal_type) {
636 case ui::MODAL_TYPE_NONE:
639 // TODO(erg): Figure out under what situations |modal_type| isn't
640 // none. The comment in desktop_native_widget_aura.cc suggests that this
646 void DesktopWindowTreeHostWayland::FlashFrame(bool flash_frame) {
651 void DesktopWindowTreeHostWayland::OnRootViewLayout() {
655 void DesktopWindowTreeHostWayland::OnNativeWidgetFocus() {
656 native_widget_delegate_->AsWidget()->GetInputMethod()->OnFocus();
659 void DesktopWindowTreeHostWayland::OnNativeWidgetBlur() {
661 native_widget_delegate_->AsWidget()->GetInputMethod()->OnBlur();
664 bool DesktopWindowTreeHostWayland::IsAnimatingClosed() const {
668 bool DesktopWindowTreeHostWayland::IsTranslucentWindowOpacitySupported() const {
672 ////////////////////////////////////////////////////////////////////////////////
673 // DesktopWindowTreeHostWayland, aura::WindowTreeHost implementation:
675 ui::EventSource* DesktopWindowTreeHostWayland::GetEventSource() {
680 gfx::AcceleratedWidget DesktopWindowTreeHostWayland::GetAcceleratedWidget() {
684 void DesktopWindowTreeHostWayland::Show() {
685 if (state_ & Visible)
688 // Window is being shown, set the state as active to be able to handle events.
692 ui::WindowStateChangeHandler::GetInstance()->SetWidgetState(window_,
694 native_widget_delegate_->OnNativeWidgetVisibilityChanged(true);
697 void DesktopWindowTreeHostWayland::Hide() {
698 if (!(state_ & Visible))
702 ui::WindowStateChangeHandler::GetInstance()->SetWidgetState(window_,
704 native_widget_delegate_->OnNativeWidgetVisibilityChanged(false);
707 gfx::Rect DesktopWindowTreeHostWayland::GetBounds() const {
711 void DesktopWindowTreeHostWayland::SetBounds(const gfx::Rect& bounds) {
712 bool origin_changed = bounds_.origin() != bounds.origin();
713 bool size_changed = bounds_.size() != bounds.size();
718 native_widget_delegate_->AsWidget()->OnNativeWidgetMove();
720 OnHostResized(bounds.size());
722 compositor()->ScheduleRedrawRect(bounds);
725 gfx::Point DesktopWindowTreeHostWayland::GetLocationOnNativeScreen() const {
726 return bounds_.origin();
729 void DesktopWindowTreeHostWayland::SetCapture() {
730 g_delegate_ozone_wayland_->SetCapture(this);
733 void DesktopWindowTreeHostWayland::ReleaseCapture() {
734 g_delegate_ozone_wayland_->SetCapture(NULL);
737 void DesktopWindowTreeHostWayland::SetCursorNative(gfx::NativeCursor cursor) {
738 // TODO(kalyan): Add support for custom cursor.
739 ui::WindowStateChangeHandler::GetInstance()->SetWidgetCursor(
740 cursor.native_type());
743 void DesktopWindowTreeHostWayland::OnCursorVisibilityChangedNative(bool show) {
744 // TODO(erg): Conditional on us enabling touch on desktop linux builds, do
745 // the same tap-to-click disabling here that chromeos does.
748 void DesktopWindowTreeHostWayland::MoveCursorToNative(
749 const gfx::Point& location) {
753 void DesktopWindowTreeHostWayland::PostNativeEvent(
754 const base::NativeEvent& native_event) {
758 ////////////////////////////////////////////////////////////////////////////////
759 // DesktopWindowTreeHostWayland, Private implementation:
761 void DesktopWindowTreeHostWayland::HandleNativeWidgetActivationChanged(
763 // We can skip during initialization phase.
770 desktop_native_widget_aura_->HandleActivationChanged(active);
771 native_widget_delegate_->AsWidget()->GetRootView()->SchedulePaint();
774 void DesktopWindowTreeHostWayland::HandleWindowResize(unsigned width,
776 unsigned current_width = bounds_.width();
777 unsigned current_height = bounds_.height();
778 if ((current_width == width) && (current_height == height)) {
779 compositor()->ScheduleRedrawRect(bounds_);
781 bounds_ = gfx::Rect(bounds_.x(), bounds_.y(), width, height);
782 OnHostResized(bounds_.size());
783 Widget* widget = native_widget_delegate_->AsWidget();
784 NonClientView* non_client_view = widget->non_client_view();
785 // non_client_view may be NULL, especially during creation.
786 if (non_client_view) {
787 non_client_view->client_view()->InvalidateLayout();
788 non_client_view->InvalidateLayout();
790 widget->GetRootView()->Layout();
794 void DesktopWindowTreeHostWayland::HandleWindowUnminimized() {
795 state_ &= ~Minimized;
796 bounds_ = previous_bounds_;
797 previous_bounds_ = gfx::Rect();
798 OnHostResized(bounds_.size());
801 void DesktopWindowTreeHostWayland::HandleCommit(const std::string& text) {
802 ui::InputMethodAuraLinux* inputMethod =
803 static_cast<ui::InputMethodAuraLinux*>(desktop_native_widget_aura_->
804 input_method_event_filter()->input_method());
805 inputMethod->OnCommit(base::string16(base::ASCIIToUTF16(text.c_str())));
808 void DesktopWindowTreeHostWayland::HandlePreeditChanged(const std::string& text,
809 const std::string& commit) {
810 ui::CompositionText composition_text;
811 composition_text.text = base::string16(base::ASCIIToUTF16(text.c_str()));
812 ui::InputMethodAuraLinux* inputMethod =
813 static_cast<ui::InputMethodAuraLinux*>(desktop_native_widget_aura_->
814 input_method_event_filter()->input_method());
815 inputMethod->OnPreeditChanged(composition_text);
819 VIEWS_EXPORT ui::NativeTheme*
820 DesktopWindowTreeHost::GetNativeTheme(aura::Window* window) {
821 const views::LinuxUI* linux_ui = views::LinuxUI::instance();
823 ui::NativeTheme* native_theme = linux_ui->GetNativeTheme(window);
828 return ui::NativeTheme::instance();