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/surface_factory_ozone.h"
27 #include "ui/views/corewm/tooltip_aura.h"
28 #include "ui/views/ime/input_method.h"
29 #include "ui/views/linux_ui/linux_ui.h"
30 #include "ui/views/views_export.h"
31 #include "ui/views/widget/desktop_aura/desktop_dispatcher_client.h"
32 #include "ui/views/widget/desktop_aura/desktop_native_cursor_manager.h"
33 #include "ui/views/widget/desktop_aura/desktop_native_widget_aura.h"
34 #include "ui/views/widget/desktop_aura/desktop_screen_position_client.h"
35 #include "ui/wm/core/input_method_event_filter.h"
36 #include "ui/wm/core/window_util.h"
37 #include "ui/wm/public/window_move_client.h"
41 WindowTreeHostDelegateWayland*
42 DesktopWindowTreeHostWayland::g_delegate_ozone_wayland_ = NULL;
44 DEFINE_WINDOW_PROPERTY_KEY(
45 aura::Window*, kViewsWindowForRootWindow, NULL);
47 DEFINE_WINDOW_PROPERTY_KEY(
48 DesktopWindowTreeHostWayland*, kHostForRootWindow, NULL);
50 DesktopWindowTreeHostWayland::DesktopWindowTreeHostWayland(
51 internal::NativeWidgetDelegate* native_widget_delegate,
52 DesktopNativeWidgetAura* desktop_native_widget_aura)
53 : aura::WindowTreeHost(),
54 state_(Uninitialized),
56 previous_bounds_(0, 0, 0, 0),
57 previous_maximize_bounds_(0, 0, 0, 0),
59 title_(base::string16()),
60 close_widget_factory_(this),
61 drag_drop_client_(NULL),
62 native_widget_delegate_(native_widget_delegate),
63 content_window_(NULL),
64 desktop_native_widget_aura_(desktop_native_widget_aura),
69 DesktopWindowTreeHostWayland::~DesktopWindowTreeHostWayland() {
70 window()->ClearProperty(kHostForRootWindow);
71 aura::client::SetWindowMoveClient(window(), NULL);
72 desktop_native_widget_aura_->OnDesktopWindowTreeHostDestroyed(this);
77 DesktopWindowTreeHostWayland*
78 DesktopWindowTreeHostWayland::GetHostForAcceleratedWidget(
79 gfx::AcceleratedWidget widget) {
80 aura::WindowTreeHost* host =
81 aura::WindowTreeHost::GetForAcceleratedWidget(widget);
83 return host ? host->window()->GetProperty(kHostForRootWindow) : NULL;
87 const std::vector<aura::Window*>&
88 DesktopWindowTreeHostWayland::GetAllOpenWindows() {
89 DCHECK(g_delegate_ozone_wayland_);
90 return g_delegate_ozone_wayland_->GetAllOpenWindows();
95 DesktopWindowTreeHostWayland::GetContentWindowForAcceleratedWidget(
96 gfx::AcceleratedWidget widget) {
97 aura::WindowTreeHost* host =
98 aura::WindowTreeHost::GetForAcceleratedWidget(widget);
101 host->window()->GetProperty(kViewsWindowForRootWindow) : NULL;
104 gfx::Rect DesktopWindowTreeHostWayland::GetBoundsInScreen() const {
108 ////////////////////////////////////////////////////////////////////////////////
109 // DesktopWindowTreeHostWayland, private:
111 void DesktopWindowTreeHostWayland::InitWaylandWindow(
112 const Widget::InitParams& params) {
113 ui::SurfaceFactoryOzone* surface_factory =
114 ui::SurfaceFactoryOzone::GetInstance();
115 window_ = surface_factory->GetAcceleratedWidget();
116 // Maintain parent child relation as done in X11 version.
117 // If we have a parent, record the parent/child relationship. We use this
118 // data during destruction to make sure that when we try to close a parent
119 // window, we also destroy all child windows.
120 if (params.parent && params.parent->GetHost()) {
121 gfx::AcceleratedWidget windowId = params.parent->GetHost()->
122 GetAcceleratedWidget();
123 window_parent_ = GetHostForAcceleratedWidget(windowId);
124 DCHECK(window_parent_);
125 window_parent_->window_children_.insert(this);
128 bounds_ = params.bounds;
129 ui::WindowStateChangeHandler* state_handler =
130 ui::WindowStateChangeHandler::GetInstance();
131 switch (params.type) {
132 case Widget::InitParams::TYPE_TOOLTIP:
133 case Widget::InitParams::TYPE_POPUP:
134 case Widget::InitParams::TYPE_MENU: {
135 // Wayland surfaces don't know their position on the screen and transient
136 // surfaces always require a parent surface for relative placement. Here
137 // there's a catch because content_shell menus don't have parent and
138 // therefore we use root window to calculate their position.
139 DesktopWindowTreeHostWayland* parent = window_parent_;
141 parent = GetHostForAcceleratedWidget(
142 g_delegate_ozone_wayland_->GetActiveWindow()->window_);
144 // Transient type expects a position relative to the parent
145 gfx::Point transientPos(bounds_.x() - parent->bounds_.x(),
146 bounds_.y() - parent->bounds_.y());
148 // Different platforms implement different input grab pointer behaviors
149 // on Chromium. While the Linux GTK+ grab button clicks but not the
150 // pointer movement, the MS Windows implementation don't implement any
151 // pointer grab. In here we're using another different behavior for
152 // Chromium, but which is the common sense on most Wayland UI
153 // environments, where the input pointer is grabbed as a whole when a
154 // menu type of window is opened. I.e. both pointer clicks and movements
155 // will be routed only to the newly created window (grab installed). For
156 // more information please refer to the Wayland protocol.
157 state_handler->SetWidgetAttributes(window_,
164 case Widget::InitParams::TYPE_BUBBLE:
165 case Widget::InitParams::TYPE_WINDOW:
166 state_handler->SetWidgetAttributes(window_,
172 case Widget::InitParams::TYPE_WINDOW_FRAMELESS:
179 CreateCompositor(GetAcceleratedWidget());
182 ////////////////////////////////////////////////////////////////////////////////
183 // DesktopWindowTreeHostWayland, DesktopWindowTreeHost implementation:
185 void DesktopWindowTreeHostWayland::Init(
186 aura::Window* content_window,
187 const Widget::InitParams& params) {
188 content_window_ = content_window;
189 // In some situations, views tries to make a zero sized window, and that
190 // makes us crash. Make sure we have valid sizes.
191 Widget::InitParams sanitized_params = params;
192 if (sanitized_params.bounds.width() == 0)
193 sanitized_params.bounds.set_width(100);
194 if (sanitized_params.bounds.height() == 0)
195 sanitized_params.bounds.set_height(100);
197 InitWaylandWindow(sanitized_params);
200 void DesktopWindowTreeHostWayland::OnNativeWidgetCreated(
201 const Widget::InitParams& params) {
202 window()->SetProperty(kViewsWindowForRootWindow, content_window_);
203 window()->SetProperty(kHostForRootWindow, this);
205 // If we're given a parent, we need to mark ourselves as transient to another
206 // window. Otherwise activation gets screwy.
207 gfx::NativeView parent = params.parent;
208 if (!params.child && params.parent)
209 wm::AddTransientChild(parent, content_window_);
211 native_widget_delegate_->OnNativeWidgetCreated(true);
213 if (!g_delegate_ozone_wayland_)
214 g_delegate_ozone_wayland_ = new WindowTreeHostDelegateWayland();
216 g_delegate_ozone_wayland_->OnRootWindowCreated(window_);
218 // Add DesktopWindowTreeHostWayland as dispatcher.
219 bool root_window = params.type == Widget::InitParams::TYPE_BUBBLE ||
220 params.type == Widget::InitParams::TYPE_WINDOW ||
221 params.type == Widget::InitParams::TYPE_WINDOW_FRAMELESS;
222 if (!window_parent_ && root_window)
223 g_delegate_ozone_wayland_->SetActiveWindow(this);
226 scoped_ptr<corewm::Tooltip>
227 DesktopWindowTreeHostWayland::CreateTooltip() {
228 return scoped_ptr<corewm::Tooltip>(
229 new corewm::TooltipAura(gfx::SCREEN_TYPE_NATIVE));
232 scoped_ptr<aura::client::DragDropClient>
233 DesktopWindowTreeHostWayland::CreateDragDropClient(
234 DesktopNativeCursorManager* cursor_manager) {
235 drag_drop_client_ = new DesktopDragDropClientWayland(window());
236 return scoped_ptr<aura::client::DragDropClient>(drag_drop_client_).Pass();
239 void DesktopWindowTreeHostWayland::Close() {
240 if (!close_widget_factory_.HasWeakPtrs()) {
241 // And we delay the close so that if we are called from an ATL callback,
242 // we don't destroy the window before the callback returned (as the caller
243 // may delete ourselves on destroy and the ATL callback would still
244 // dereference us when the callback returns).
245 base::MessageLoop::current()->PostTask(
247 base::Bind(&DesktopWindowTreeHostWayland::CloseNow,
248 close_widget_factory_.GetWeakPtr()));
252 void DesktopWindowTreeHostWayland::CloseNow() {
253 DCHECK(g_delegate_ozone_wayland_);
254 unsigned widgetId = window_;
255 native_widget_delegate_->OnNativeWidgetDestroying();
257 // If we have children, close them. Use a copy for iteration because they'll
258 // remove themselves.
259 std::set<DesktopWindowTreeHostWayland*> window_children_copy =
261 for (std::set<DesktopWindowTreeHostWayland*>::iterator it =
262 window_children_copy.begin(); it != window_children_copy.end();
266 DCHECK(window_children_.empty());
268 // If we have a parent, remove ourselves from its children list.
270 window_parent_->window_children_.erase(this);
272 g_delegate_ozone_wayland_->OnRootWindowClosed(widgetId);
273 // Destroy the compositor before destroying the window since shutdown
274 // may try to swap, and the swap without a window causes an error, which
275 // causes a crash with in-process renderer.
277 window_parent_ = NULL;
278 if (!g_delegate_ozone_wayland_->GetActiveWindow()) {
279 // We have no open windows, free g_delegate_ozone_wayland_.
280 delete g_delegate_ozone_wayland_;
281 g_delegate_ozone_wayland_ = NULL;
284 desktop_native_widget_aura_->OnHostClosed();
287 aura::WindowTreeHost* DesktopWindowTreeHostWayland::AsWindowTreeHost() {
291 void DesktopWindowTreeHostWayland::ShowWindowWithState(
292 ui::WindowShowState show_state) {
293 if (show_state != ui::SHOW_STATE_DEFAULT &&
294 show_state != ui::SHOW_STATE_NORMAL) {
295 // Only forwarding to Show().
300 if (show_state == ui::SHOW_STATE_MAXIMIZED)
303 // Set initial focus for root window.
305 native_widget_delegate_->AsWidget()->SetInitialFocus(show_state);
308 void DesktopWindowTreeHostWayland::ShowMaximizedWithBounds(
309 const gfx::Rect& restored_bounds) {
311 previous_bounds_ = restored_bounds;
315 bool DesktopWindowTreeHostWayland::IsVisible() const {
316 return state_ & Visible;
319 void DesktopWindowTreeHostWayland::SetSize(const gfx::Size& size) {
320 gfx::Rect new_bounds = bounds_;
321 new_bounds.set_size(size);
322 SetBounds(new_bounds);
325 void DesktopWindowTreeHostWayland::StackAtTop() {
328 void DesktopWindowTreeHostWayland::CenterWindow(const gfx::Size& size) {
329 gfx::Rect parent_bounds = GetWorkAreaBoundsInScreen();
331 // If |window_|'s transient parent bounds are big enough to contain |size|,
333 if (wm::GetTransientParent(content_window_)) {
334 gfx::Rect transient_parent_rect =
335 wm::GetTransientParent(content_window_)->GetBoundsInScreen();
336 if (transient_parent_rect.height() >= size.height() &&
337 transient_parent_rect.width() >= size.width()) {
338 parent_bounds = transient_parent_rect;
342 gfx::Rect window_bounds(
343 parent_bounds.x() + (parent_bounds.width() - size.width()) / 2,
344 parent_bounds.y() + (parent_bounds.height() - size.height()) / 2,
347 // Don't size the window bigger than the parent, otherwise the user may not be
348 // able to close or move it.
349 window_bounds.AdjustToFit(parent_bounds);
350 SetBounds(window_bounds);
353 void DesktopWindowTreeHostWayland::GetWindowPlacement(
355 ui::WindowShowState* show_state) const {
356 *bounds = GetRestoredBounds();
358 if (IsFullscreen()) {
359 *show_state = ui::SHOW_STATE_FULLSCREEN;
360 } else if (IsMinimized()) {
361 *show_state = ui::SHOW_STATE_MINIMIZED;
362 } else if (IsMaximized()) {
363 *show_state = ui::SHOW_STATE_MAXIMIZED;
364 } else if (!IsActive()) {
365 *show_state = ui::SHOW_STATE_INACTIVE;
367 *show_state = ui::SHOW_STATE_NORMAL;
371 gfx::Rect DesktopWindowTreeHostWayland::GetWindowBoundsInScreen() const {
375 gfx::Rect DesktopWindowTreeHostWayland::GetClientAreaBoundsInScreen() const {
376 // TODO(erg): The NativeWidgetAura version returns |bounds_|, claiming its
377 // needed for View::ConvertPointToScreen() to work
378 // correctly. DesktopWindowTreeHostWin::GetClientAreaBoundsInScreen() just
379 // asks windows what it thinks the client rect is.
381 // Attempts to calculate the rect by asking the NonClientFrameView what it
382 // thought its GetBoundsForClientView() were broke combobox drop down
387 gfx::Rect DesktopWindowTreeHostWayland::GetRestoredBounds() const {
388 if (!previous_bounds_.IsEmpty())
389 return previous_bounds_;
391 return GetWindowBoundsInScreen();
394 gfx::Rect DesktopWindowTreeHostWayland::GetWorkAreaBoundsInScreen() const {
395 // TODO(kalyan): Take into account wm decorations. i.e Dock, panel etc.
396 gfx::Screen *screen = gfx::Screen::GetScreenByType(gfx::SCREEN_TYPE_NATIVE);
398 NOTREACHED() << "Unable to retrieve valid gfx::Screen";
400 gfx::Display display = screen->GetPrimaryDisplay();
401 return display.bounds();
404 void DesktopWindowTreeHostWayland::SetShape(gfx::NativeRegion native_region) {
409 void DesktopWindowTreeHostWayland::Activate() {
414 if (state_ & Visible)
415 ui::WindowStateChangeHandler::GetInstance()->SetWidgetState(window_,
419 void DesktopWindowTreeHostWayland::Deactivate() {
420 if (!(state_ & Active))
424 ui::WindowStateChangeHandler::GetInstance()->SetWidgetState(window_,
428 bool DesktopWindowTreeHostWayland::IsActive() const {
429 return state_ & Active;
432 void DesktopWindowTreeHostWayland::Maximize() {
433 if (state_ & Maximized)
435 if (IsMinimized() && !window_parent_)
436 native_widget_delegate_->AsWidget()->SetInitialFocus(ui::SHOW_STATE_NORMAL);
439 state_ &= ~Minimized;
441 previous_bounds_ = bounds_;
442 ui::WindowStateChangeHandler::GetInstance()->SetWidgetState(window_,
446 void DesktopWindowTreeHostWayland::Minimize() {
447 if (state_ & Minimized)
450 state_ &= ~Maximized;
453 previous_bounds_ = bounds_;
454 ui::WindowStateChangeHandler::GetInstance()->SetWidgetState(window_,
458 void DesktopWindowTreeHostWayland::Restore() {
462 if (IsMinimized() && !window_parent_)
463 native_widget_delegate_->AsWidget()->SetInitialFocus(ui::SHOW_STATE_NORMAL);
464 state_ &= ~Maximized;
465 state_ &= ~Minimized;
467 bounds_ = previous_bounds_;
468 previous_bounds_ = gfx::Rect();
469 ui::WindowStateChangeHandler::GetInstance()->SetWidgetState(
470 window_, ui::RESTORE, bounds_.width(), bounds_.height());
471 native_widget_delegate_->AsWidget()->OnNativeWidgetMove();
472 OnHostResized(bounds_.size());
475 bool DesktopWindowTreeHostWayland::IsMaximized() const {
476 return state_ & Maximized;
479 bool DesktopWindowTreeHostWayland::IsMinimized() const {
480 return state_ & Minimized;
483 void DesktopWindowTreeHostWayland::OnCaptureReleased() {
484 OnHostLostWindowCapture();
485 native_widget_delegate_->OnMouseCaptureLost();
488 bool DesktopWindowTreeHostWayland::HasCapture() const {
489 return g_delegate_ozone_wayland_->GetCurrentCapture() == this;
492 bool DesktopWindowTreeHostWayland::IsAlwaysOnTop() const {
497 void DesktopWindowTreeHostWayland::SetVisibleOnAllWorkspaces(
498 bool always_visible) {
502 void DesktopWindowTreeHostWayland::SetAlwaysOnTop(bool always_on_top) {
507 bool DesktopWindowTreeHostWayland::SetWindowTitle(const base::string16& title) {
508 if (title.compare(title_)) {
509 ui::WindowStateChangeHandler::GetInstance()->SetWidgetTitle(window_, title);
517 void DesktopWindowTreeHostWayland::ClearNativeFocus() {
518 // This method is weird and misnamed. Instead of clearing the native focus,
519 // it sets the focus to our |content_window_|, which will trigger a cascade
520 // of focus changes into views.
521 if (content_window_ && aura::client::GetFocusClient(content_window_) &&
522 content_window_->Contains(
523 aura::client::GetFocusClient(content_window_)->GetFocusedWindow())) {
524 aura::client::GetFocusClient(content_window_)->FocusWindow(content_window_);
528 Widget::MoveLoopResult DesktopWindowTreeHostWayland::RunMoveLoop(
529 const gfx::Vector2d& drag_offset,
530 Widget::MoveLoopSource source,
531 Widget::MoveLoopEscapeBehavior escape_behavior) {
533 return Widget::MOVE_LOOP_SUCCESSFUL;
536 void DesktopWindowTreeHostWayland::EndMoveLoop() {
540 void DesktopWindowTreeHostWayland::SetVisibilityChangedAnimationsEnabled(
542 // Much like the previous NativeWidgetGtk, we don't have anything to do here.
545 bool DesktopWindowTreeHostWayland::ShouldUseNativeFrame() const {
549 bool DesktopWindowTreeHostWayland::ShouldWindowContentsBeTransparent() const {
553 void DesktopWindowTreeHostWayland::FrameTypeChanged() {
554 Widget::FrameType new_type =
555 native_widget_delegate_->AsWidget()->frame_type();
556 if (new_type == Widget::FRAME_TYPE_DEFAULT) {
557 // The default is determined by Widget::InitParams::remove_standard_frame
558 // and does not change.
562 // Replace the frame and layout the contents. Even though we don't have a
563 // swapable glass frame like on Windows, we still replace the frame because
564 // the button assets don't update otherwise.
565 native_widget_delegate_->AsWidget()->non_client_view()->UpdateFrame();
568 void DesktopWindowTreeHostWayland::SetFullscreen(bool fullscreen) {
569 if ((state_ & FullScreen) == fullscreen)
573 state_ |= FullScreen;
576 state_ &= ~FullScreen;
579 if (!(state_ & FullScreen)) {
580 if (state_ & Maximized) {
581 previous_bounds_ = previous_maximize_bounds_;
582 previous_maximize_bounds_ = gfx::Rect();
583 ui::WindowStateChangeHandler::GetInstance()->SetWidgetState(
584 window_, ui::MAXIMIZED);
589 if (state_ & Maximized)
590 previous_maximize_bounds_ = previous_bounds_;
592 previous_bounds_ = bounds_;
593 gfx::Screen *screen = gfx::Screen::GetScreenByType(gfx::SCREEN_TYPE_NATIVE);
595 NOTREACHED() << "Unable to retrieve valid gfx::Screen";
597 bounds_ = screen->GetPrimaryDisplay().bounds();
598 // We could use HandleConfigure in ShellSurface to set the correct bounds of
599 // egl window associated with this opaque handle. How ever, this would need
600 // to handle race conditions and ensure correct size is set for
601 // wl_egl_window_resize before eglsurface is resized. Passing window size
602 // attributes already here, ensures that wl_egl_window_resize is resized
603 // before eglsurface is resized. This doesn't add any extra overhead as the
604 // IPC call needs to be done.
605 ui::WindowStateChangeHandler::GetInstance()->SetWidgetState(
606 window_, ui::FULLSCREEN, bounds_.width(), bounds_.height());
607 OnHostResized(bounds_.size());
611 bool DesktopWindowTreeHostWayland::IsFullscreen() const {
612 return state_ & FullScreen;
615 void DesktopWindowTreeHostWayland::SetOpacity(unsigned char opacity) {
620 void DesktopWindowTreeHostWayland::SetWindowIcons(
621 const gfx::ImageSkia& window_icon, const gfx::ImageSkia& app_icon) {
626 void DesktopWindowTreeHostWayland::InitModalType(ui::ModalType modal_type) {
627 switch (modal_type) {
628 case ui::MODAL_TYPE_NONE:
631 // TODO(erg): Figure out under what situations |modal_type| isn't
632 // none. The comment in desktop_native_widget_aura.cc suggests that this
638 void DesktopWindowTreeHostWayland::FlashFrame(bool flash_frame) {
643 void DesktopWindowTreeHostWayland::OnRootViewLayout() const {
647 void DesktopWindowTreeHostWayland::OnNativeWidgetFocus() {
648 native_widget_delegate_->AsWidget()->GetInputMethod()->OnFocus();
651 void DesktopWindowTreeHostWayland::OnNativeWidgetBlur() {
653 native_widget_delegate_->AsWidget()->GetInputMethod()->OnBlur();
656 bool DesktopWindowTreeHostWayland::IsAnimatingClosed() const {
660 bool DesktopWindowTreeHostWayland::IsTranslucentWindowOpacitySupported() const {
664 ////////////////////////////////////////////////////////////////////////////////
665 // DesktopWindowTreeHostWayland, aura::WindowTreeHost implementation:
667 ui::EventSource* DesktopWindowTreeHostWayland::GetEventSource() {
672 gfx::AcceleratedWidget DesktopWindowTreeHostWayland::GetAcceleratedWidget() {
676 void DesktopWindowTreeHostWayland::Show() {
677 if (state_ & Visible)
680 // Window is being shown, set the state as active to be able to handle events.
684 ui::WindowStateChangeHandler::GetInstance()->SetWidgetState(window_,
686 native_widget_delegate_->OnNativeWidgetVisibilityChanged(true);
689 void DesktopWindowTreeHostWayland::Hide() {
690 if (!(state_ & Visible))
694 ui::WindowStateChangeHandler::GetInstance()->SetWidgetState(window_,
696 native_widget_delegate_->OnNativeWidgetVisibilityChanged(false);
699 gfx::Rect DesktopWindowTreeHostWayland::GetBounds() const {
703 void DesktopWindowTreeHostWayland::SetBounds(const gfx::Rect& bounds) {
704 bool origin_changed = bounds_.origin() != bounds.origin();
705 bool size_changed = bounds_.size() != bounds.size();
710 native_widget_delegate_->AsWidget()->OnNativeWidgetMove();
712 OnHostResized(bounds.size());
714 compositor()->ScheduleRedrawRect(bounds);
717 gfx::Point DesktopWindowTreeHostWayland::GetLocationOnNativeScreen() const {
718 return bounds_.origin();
721 void DesktopWindowTreeHostWayland::SetCapture() {
722 g_delegate_ozone_wayland_->SetCapture(this);
725 void DesktopWindowTreeHostWayland::ReleaseCapture() {
726 g_delegate_ozone_wayland_->SetCapture(NULL);
729 void DesktopWindowTreeHostWayland::SetCursorNative(gfx::NativeCursor cursor) {
730 // TODO(kalyan): Add support for custom cursor.
731 ui::WindowStateChangeHandler::GetInstance()->SetWidgetCursor(
732 cursor.native_type());
735 void DesktopWindowTreeHostWayland::OnCursorVisibilityChangedNative(bool show) {
736 // TODO(erg): Conditional on us enabling touch on desktop linux builds, do
737 // the same tap-to-click disabling here that chromeos does.
740 void DesktopWindowTreeHostWayland::MoveCursorToNative(
741 const gfx::Point& location) {
745 void DesktopWindowTreeHostWayland::PostNativeEvent(
746 const base::NativeEvent& native_event) {
750 void DesktopWindowTreeHostWayland::OnDeviceScaleFactorChanged(
751 float device_scale_factor) {
754 ////////////////////////////////////////////////////////////////////////////////
755 // DesktopWindowTreeHostWayland, Private implementation:
757 void DesktopWindowTreeHostWayland::HandleNativeWidgetActivationChanged(
759 // We can skip during initialization phase.
766 desktop_native_widget_aura_->HandleActivationChanged(active);
767 native_widget_delegate_->AsWidget()->GetRootView()->SchedulePaint();
770 void DesktopWindowTreeHostWayland::HandleWindowResize(unsigned width,
772 unsigned current_width = bounds_.width();
773 unsigned current_height = bounds_.height();
774 if ((current_width == width) && (current_height == height)) {
775 compositor()->ScheduleRedrawRect(bounds_);
777 bounds_ = gfx::Rect(bounds_.x(), bounds_.y(), width, height);
778 OnHostResized(bounds_.size());
779 Widget* widget = native_widget_delegate_->AsWidget();
780 NonClientView* non_client_view = widget->non_client_view();
781 // non_client_view may be NULL, especially during creation.
782 if (non_client_view) {
783 non_client_view->client_view()->InvalidateLayout();
784 non_client_view->InvalidateLayout();
786 widget->GetRootView()->Layout();
790 void DesktopWindowTreeHostWayland::HandleCommit(const std::string& text) {
791 ui::InputMethodAuraLinux* inputMethod =
792 static_cast<ui::InputMethodAuraLinux*>(desktop_native_widget_aura_->
793 input_method_event_filter()->input_method());
794 inputMethod->OnCommit(base::string16(base::ASCIIToUTF16(text.c_str())));
797 void DesktopWindowTreeHostWayland::HandlePreeditChanged(const std::string& text,
798 const std::string& commit) {
799 ui::CompositionText composition_text;
800 composition_text.text = base::string16(base::ASCIIToUTF16(text.c_str()));
801 ui::InputMethodAuraLinux* inputMethod =
802 static_cast<ui::InputMethodAuraLinux*>(desktop_native_widget_aura_->
803 input_method_event_filter()->input_method());
804 inputMethod->OnPreeditChanged(composition_text);
808 VIEWS_EXPORT ui::NativeTheme*
809 DesktopWindowTreeHost::GetNativeTheme(aura::Window* window) {
810 const views::LinuxUI* linux_ui = views::LinuxUI::instance();
812 ui::NativeTheme* native_theme = linux_ui->GetNativeTheme(window);
817 return ui::NativeTheme::instance();