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

Side by Side Diff: ui/views/mus/native_widget_mus.cc

Issue 2611773002: Removes code using mus client lib (Closed)
Patch Set: dont run on linux Created 3 years, 11 months 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
« no previous file with comments | « ui/views/mus/native_widget_mus.h ('k') | ui/views/mus/native_widget_mus_unittest.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 2015 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 // This has to be before any other includes, else default is picked up.
6 // See base/logging for details on this.
7 #define NOTIMPLEMENTED_POLICY 5
8
9 #include "ui/views/mus/native_widget_mus.h"
10
11 #include <map>
12 #include <utility>
13 #include <vector>
14
15 #include "base/callback.h"
16 #include "base/macros.h"
17 #include "base/memory/ptr_util.h"
18 #include "base/message_loop/message_loop.h"
19 #include "base/run_loop.h"
20 #include "base/threading/thread_task_runner_handle.h"
21 #include "services/ui/public/cpp/property_type_converters.h"
22 #include "services/ui/public/cpp/window.h"
23 #include "services/ui/public/cpp/window_observer.h"
24 #include "services/ui/public/cpp/window_property.h"
25 #include "services/ui/public/cpp/window_tree_client.h"
26 #include "services/ui/public/interfaces/cursor.mojom.h"
27 #include "services/ui/public/interfaces/window_manager.mojom.h"
28 #include "services/ui/public/interfaces/window_manager_constants.mojom.h"
29 #include "services/ui/public/interfaces/window_tree.mojom.h"
30 #include "ui/aura/client/default_capture_client.h"
31 #include "ui/aura/client/window_parenting_client.h"
32 #include "ui/aura/layout_manager.h"
33 #include "ui/aura/mus/mus_util.h"
34 #include "ui/aura/mus/property_converter.h"
35 #include "ui/aura/window.h"
36 #include "ui/aura/window_property.h"
37 #include "ui/base/hit_test.h"
38 #include "ui/display/display.h"
39 #include "ui/display/screen.h"
40 #include "ui/events/event.h"
41 #include "ui/gfx/canvas.h"
42 #include "ui/gfx/geometry/dip_util.h"
43 #include "ui/gfx/path.h"
44 #include "ui/native_theme/native_theme.h"
45 #include "ui/platform_window/platform_window_delegate.h"
46 #include "ui/views/corewm/tooltip.h"
47 #include "ui/views/corewm/tooltip_aura.h"
48 #include "ui/views/corewm/tooltip_controller.h"
49 #include "ui/views/drag_utils.h"
50 #include "ui/views/mus/drag_drop_client_mus.h"
51 #include "ui/views/mus/drop_target_mus.h"
52 #include "ui/views/mus/input_method_mus.h"
53 #include "ui/views/mus/window_manager_connection.h"
54 #include "ui/views/mus/window_manager_constants_converters.h"
55 #include "ui/views/mus/window_manager_frame_values.h"
56 #include "ui/views/mus/window_tree_host_mus.h"
57 #include "ui/views/widget/drop_helper.h"
58 #include "ui/views/widget/native_widget_aura.h"
59 #include "ui/views/widget/tooltip_manager_aura.h"
60 #include "ui/views/widget/widget_delegate.h"
61 #include "ui/views/window/custom_frame_view.h"
62 #include "ui/wm/core/base_focus_rules.h"
63 #include "ui/wm/core/capture_controller.h"
64 #include "ui/wm/core/cursor_manager.h"
65 #include "ui/wm/core/default_screen_position_client.h"
66 #include "ui/wm/core/focus_controller.h"
67 #include "ui/wm/core/native_cursor_manager.h"
68
69 DECLARE_WINDOW_PROPERTY_TYPE(ui::Window*);
70
71 using PrimitiveType = aura::PropertyConverter::PrimitiveType;
72 using ui::mojom::EventResult;
73
74 namespace views {
75 namespace {
76
77 DEFINE_WINDOW_PROPERTY_KEY(ui::Window*, kMusWindow, nullptr);
78
79 MUS_DEFINE_WINDOW_PROPERTY_KEY(NativeWidgetMus*, kNativeWidgetMusKey, nullptr);
80
81 // This ensures that only the top-level aura Window can be activated.
82 class FocusRulesImpl : public wm::BaseFocusRules {
83 public:
84 explicit FocusRulesImpl(aura::Window* root) : root_(root) {}
85 ~FocusRulesImpl() override {}
86
87 bool SupportsChildActivation(aura::Window* window) const override {
88 return root_ == window;
89 }
90
91 private:
92 aura::Window* root_;
93
94 DISALLOW_COPY_AND_ASSIGN(FocusRulesImpl);
95 };
96
97 // This makes sure that an aura::Window focused (or activated) through the
98 // aura::client::FocusClient (or ActivationClient) focuses (or activates) the
99 // corresponding ui::Window too.
100 class FocusControllerMus : public wm::FocusController {
101 public:
102 explicit FocusControllerMus(wm::FocusRules* rules) : FocusController(rules) {}
103 ~FocusControllerMus() override {}
104
105 private:
106 void FocusWindow(aura::Window* window) override {
107 FocusController::FocusWindow(window);
108 if (window) {
109 ui::Window* mus_window = window->GetRootWindow()->GetProperty(kMusWindow);
110 if (mus_window)
111 mus_window->SetFocus();
112 }
113 }
114
115 DISALLOW_COPY_AND_ASSIGN(FocusControllerMus);
116 };
117
118 class ContentWindowLayoutManager : public aura::LayoutManager {
119 public:
120 ContentWindowLayoutManager(aura::Window* outer, aura::Window* inner)
121 : outer_(outer), inner_(inner) {}
122 ~ContentWindowLayoutManager() override {}
123
124 private:
125 // aura::LayoutManager:
126 void OnWindowResized() override { inner_->SetBounds(outer_->bounds()); }
127 void OnWindowAddedToLayout(aura::Window* child) override {
128 OnWindowResized();
129 }
130 void OnWillRemoveWindowFromLayout(aura::Window* child) override {}
131 void OnWindowRemovedFromLayout(aura::Window* child) override {}
132 void OnChildWindowVisibilityChanged(aura::Window* child,
133 bool visible) override {}
134 void SetChildBounds(aura::Window* child,
135 const gfx::Rect& requested_bounds) override {
136 SetChildBoundsDirect(child, requested_bounds);
137 }
138
139 aura::Window* outer_;
140 aura::Window* inner_;
141
142 DISALLOW_COPY_AND_ASSIGN(ContentWindowLayoutManager);
143 };
144
145 class NativeWidgetMusWindowParentingClient
146 : public aura::client::WindowParentingClient {
147 public:
148 explicit NativeWidgetMusWindowParentingClient(aura::Window* root_window)
149 : root_window_(root_window) {
150 aura::client::SetWindowParentingClient(root_window_, this);
151 }
152 ~NativeWidgetMusWindowParentingClient() override {
153 aura::client::SetWindowParentingClient(root_window_, nullptr);
154 }
155
156 // Overridden from client::WindowParentingClient:
157 aura::Window* GetDefaultParent(aura::Window* context,
158 aura::Window* window,
159 const gfx::Rect& bounds) override {
160 return root_window_;
161 }
162
163 private:
164 aura::Window* root_window_;
165
166 DISALLOW_COPY_AND_ASSIGN(NativeWidgetMusWindowParentingClient);
167 };
168
169 // A screen position client that applies the offset of the ui::Window.
170 class ScreenPositionClientMus : public wm::DefaultScreenPositionClient {
171 public:
172 explicit ScreenPositionClientMus(ui::Window* mus_window)
173 : mus_window_(mus_window) {}
174 ~ScreenPositionClientMus() override {}
175
176 // wm::DefaultScreenPositionClient:
177 void ConvertPointToScreen(const aura::Window* window,
178 gfx::Point* point) override {
179 wm::DefaultScreenPositionClient::ConvertPointToScreen(window, point);
180 gfx::Rect mus_bounds = mus_window_->GetBoundsInRoot();
181 point->Offset(-mus_bounds.x(), -mus_bounds.y());
182 }
183 void ConvertPointFromScreen(const aura::Window* window,
184 gfx::Point* point) override {
185 gfx::Rect mus_bounds = mus_window_->GetBoundsInRoot();
186 point->Offset(mus_bounds.x(), mus_bounds.y());
187 wm::DefaultScreenPositionClient::ConvertPointFromScreen(window, point);
188 }
189
190 private:
191 ui::Window* mus_window_;
192
193 DISALLOW_COPY_AND_ASSIGN(ScreenPositionClientMus);
194 };
195
196 class NativeCursorManagerMus : public wm::NativeCursorManager {
197 public:
198 explicit NativeCursorManagerMus(ui::Window* mus_window)
199 : mus_window_(mus_window) {}
200 ~NativeCursorManagerMus() override {}
201
202 // wm::NativeCursorManager:
203 void SetDisplay(const display::Display& display,
204 wm::NativeCursorManagerDelegate* delegate) override {
205 // We ignore this entirely, as cursor are set on the client.
206 }
207
208 void SetCursor(gfx::NativeCursor cursor,
209 wm::NativeCursorManagerDelegate* delegate) override {
210 mus_window_->SetPredefinedCursor(ui::mojom::Cursor(cursor.native_type()));
211 delegate->CommitCursor(cursor);
212 }
213
214 void SetVisibility(bool visible,
215 wm::NativeCursorManagerDelegate* delegate) override {
216 delegate->CommitVisibility(visible);
217
218 if (visible)
219 SetCursor(delegate->GetCursor(), delegate);
220 else
221 mus_window_->SetPredefinedCursor(ui::mojom::Cursor::NONE);
222 }
223
224 void SetCursorSet(ui::CursorSetType cursor_set,
225 wm::NativeCursorManagerDelegate* delegate) override {
226 // TODO(erg): For now, ignore the difference between SET_NORMAL and
227 // SET_LARGE here. This feels like a thing that mus should decide instead.
228 //
229 // Also, it's NOTIMPLEMENTED() in the desktop version!? Including not
230 // acknowledging the call in the delegate.
231 NOTIMPLEMENTED();
232 }
233
234 void SetMouseEventsEnabled(
235 bool enabled,
236 wm::NativeCursorManagerDelegate* delegate) override {
237 // TODO(erg): How do we actually implement this?
238 //
239 // Mouse event dispatch is potentially done in a different process,
240 // definitely in a different mojo service. Each app is fairly locked down.
241 delegate->CommitMouseEventsEnabled(enabled);
242 NOTIMPLEMENTED();
243 }
244
245 private:
246 ui::Window* mus_window_;
247
248 DISALLOW_COPY_AND_ASSIGN(NativeCursorManagerMus);
249 };
250
251 // As the window manager renderers the non-client decorations this class does
252 // very little but honor the client area insets from the window manager.
253 class ClientSideNonClientFrameView : public NonClientFrameView {
254 public:
255 explicit ClientSideNonClientFrameView(views::Widget* widget)
256 : widget_(widget) {}
257 ~ClientSideNonClientFrameView() override {}
258
259 private:
260 // Returns the default values of client area insets from the window manager.
261 static gfx::Insets GetDefaultWindowManagerInsets(bool is_maximized) {
262 const WindowManagerFrameValues& values =
263 WindowManagerFrameValues::instance();
264 return is_maximized ? values.maximized_insets : values.normal_insets;
265 }
266
267 // NonClientFrameView:
268 gfx::Rect GetBoundsForClientView() const override {
269 gfx::Rect result(GetLocalBounds());
270 if (widget_->IsFullscreen())
271 return result;
272 result.Inset(GetDefaultWindowManagerInsets(widget_->IsMaximized()));
273 return result;
274 }
275 gfx::Rect GetWindowBoundsForClientBounds(
276 const gfx::Rect& client_bounds) const override {
277 if (widget_->IsFullscreen())
278 return client_bounds;
279
280 const gfx::Insets insets(
281 GetDefaultWindowManagerInsets(widget_->IsMaximized()));
282 return gfx::Rect(client_bounds.x() - insets.left(),
283 client_bounds.y() - insets.top(),
284 client_bounds.width() + insets.width(),
285 client_bounds.height() + insets.height());
286 }
287 int NonClientHitTest(const gfx::Point& point) override { return HTNOWHERE; }
288 void GetWindowMask(const gfx::Size& size, gfx::Path* window_mask) override {
289 // The window manager provides the shape; do nothing.
290 }
291 void ResetWindowControls() override {
292 // TODO(sky): push to wm?
293 }
294
295 // These have no implementation. The Window Manager handles the actual
296 // rendering of the icon/title. See NonClientFrameViewMash. The values
297 // associated with these methods are pushed to the server by the way of
298 // NativeWidgetMus functions.
299 void UpdateWindowIcon() override {}
300 void UpdateWindowTitle() override {}
301 void SizeConstraintsChanged() override {}
302
303 gfx::Size GetPreferredSize() const override {
304 return widget_->non_client_view()
305 ->GetWindowBoundsForClientBounds(
306 gfx::Rect(widget_->client_view()->GetPreferredSize()))
307 .size();
308 }
309 gfx::Size GetMinimumSize() const override {
310 return widget_->non_client_view()
311 ->GetWindowBoundsForClientBounds(
312 gfx::Rect(widget_->client_view()->GetMinimumSize()))
313 .size();
314 }
315 gfx::Size GetMaximumSize() const override {
316 gfx::Size max_size = widget_->client_view()->GetMaximumSize();
317 gfx::Size converted_size =
318 widget_->non_client_view()
319 ->GetWindowBoundsForClientBounds(gfx::Rect(max_size))
320 .size();
321 return gfx::Size(max_size.width() == 0 ? 0 : converted_size.width(),
322 max_size.height() == 0 ? 0 : converted_size.height());
323 }
324
325 views::Widget* widget_;
326
327 DISALLOW_COPY_AND_ASSIGN(ClientSideNonClientFrameView);
328 };
329
330 // Handles acknowledgment of an input event, either immediately when a nested
331 // message loop starts, or upon destruction.
332 class EventAckHandler : public base::MessageLoop::NestingObserver {
333 public:
334 explicit EventAckHandler(
335 std::unique_ptr<base::Callback<void(EventResult)>> ack_callback)
336 : ack_callback_(std::move(ack_callback)) {
337 DCHECK(ack_callback_);
338 base::MessageLoop::current()->AddNestingObserver(this);
339 }
340
341 ~EventAckHandler() override {
342 base::MessageLoop::current()->RemoveNestingObserver(this);
343 if (ack_callback_) {
344 ack_callback_->Run(handled_ ? EventResult::HANDLED
345 : EventResult::UNHANDLED);
346 }
347 }
348
349 void set_handled(bool handled) { handled_ = handled; }
350
351 // base::MessageLoop::NestingObserver:
352 void OnBeginNestedMessageLoop() override {
353 // Acknowledge the event immediately if a nested message loop starts.
354 // Otherwise we appear unresponsive for the life of the nested message loop.
355 if (ack_callback_) {
356 ack_callback_->Run(EventResult::HANDLED);
357 ack_callback_.reset();
358 }
359 }
360
361 private:
362 std::unique_ptr<base::Callback<void(EventResult)>> ack_callback_;
363 bool handled_ = false;
364
365 DISALLOW_COPY_AND_ASSIGN(EventAckHandler);
366 };
367
368 void OnMoveLoopEnd(bool* out_success,
369 base::Closure quit_closure,
370 bool in_success) {
371 *out_success = in_success;
372 quit_closure.Run();
373 }
374
375 ui::mojom::ShowState GetShowState(const ui::Window* window) {
376 if (!window ||
377 !window->HasSharedProperty(
378 ui::mojom::WindowManager::kShowState_Property)) {
379 return ui::mojom::ShowState::DEFAULT;
380 }
381
382 return static_cast<ui::mojom::ShowState>(
383 window->GetSharedProperty<PrimitiveType>(
384 ui::mojom::WindowManager::kShowState_Property));
385 }
386
387 // Set the app or window icon property for the window.
388 void SetIconProperty(ui::Window* window,
389 const char* const property,
390 const gfx::ImageSkia& icon) {
391 // TODO(crbug.com/667566): Support additional scales or gfx::Image[Skia].
392 SkBitmap bitmap = icon.GetRepresentation(1.f).sk_bitmap();
393 if (!bitmap.isNull())
394 window->SetSharedProperty<SkBitmap>(property, bitmap);
395 else if (window->HasSharedProperty(property))
396 window->ClearSharedProperty(property);
397 }
398
399 // Helper function to get the device_scale_factor() of the display::Display
400 // nearest to |window|.
401 float ScaleFactorForDisplay(aura::Window* window) {
402 return display::Screen::GetScreen()
403 ->GetDisplayNearestWindow(window)
404 .device_scale_factor();
405 }
406
407 } // namespace
408
409 class NativeWidgetMus::MusWindowObserver : public ui::WindowObserver {
410 public:
411 explicit MusWindowObserver(NativeWidgetMus* native_widget_mus)
412 : native_widget_mus_(native_widget_mus),
413 show_state_(ui::mojom::ShowState::DEFAULT) {
414 mus_window()->AddObserver(this);
415 }
416
417 ~MusWindowObserver() override {
418 mus_window()->RemoveObserver(this);
419 }
420
421 // ui::WindowObserver:
422 void OnWindowVisibilityChanging(ui::Window* window, bool visible) override {
423 native_widget_mus_->OnMusWindowVisibilityChanging(window, visible);
424 }
425 void OnWindowVisibilityChanged(ui::Window* window, bool visible) override {
426 native_widget_mus_->OnMusWindowVisibilityChanged(window, visible);
427 }
428 void OnWindowPredefinedCursorChanged(ui::Window* window,
429 ui::mojom::Cursor cursor) override {
430 DCHECK_EQ(window, mus_window());
431 native_widget_mus_->set_last_cursor(cursor);
432 }
433 void OnWindowSharedPropertyChanged(
434 ui::Window* window,
435 const std::string& name,
436 const std::vector<uint8_t>* old_data,
437 const std::vector<uint8_t>* new_data) override {
438 if (name != ui::mojom::WindowManager::kShowState_Property)
439 return;
440 const ui::mojom::ShowState show_state = GetShowState(window);
441 if (show_state == show_state_)
442 return;
443 show_state_ = show_state;
444 ui::PlatformWindowState state = ui::PLATFORM_WINDOW_STATE_UNKNOWN;
445 switch (show_state_) {
446 case ui::mojom::ShowState::MINIMIZED:
447 state = ui::PLATFORM_WINDOW_STATE_MINIMIZED;
448 break;
449 case ui::mojom::ShowState::MAXIMIZED:
450 state = ui::PLATFORM_WINDOW_STATE_MAXIMIZED;
451 break;
452 case ui::mojom::ShowState::DEFAULT:
453 case ui::mojom::ShowState::INACTIVE:
454 case ui::mojom::ShowState::NORMAL:
455 case ui::mojom::ShowState::DOCKED:
456 // TODO(sky): support docked.
457 state = ui::PLATFORM_WINDOW_STATE_NORMAL;
458 break;
459 case ui::mojom::ShowState::FULLSCREEN:
460 state = ui::PLATFORM_WINDOW_STATE_FULLSCREEN;
461 break;
462 }
463 platform_window_delegate()->OnWindowStateChanged(state);
464 }
465 void OnWindowDestroyed(ui::Window* window) override {
466 DCHECK_EQ(mus_window(), window);
467 platform_window_delegate()->OnClosed();
468 }
469 void OnWindowBoundsChanging(ui::Window* window,
470 const gfx::Rect& old_bounds,
471 const gfx::Rect& new_bounds) override {
472 DCHECK_EQ(window, mus_window());
473 window_tree_host()->SetBoundsInPixels(gfx::ConvertRectToPixel(
474 ScaleFactorForDisplay(aura_window()), new_bounds));
475 }
476 void OnWindowFocusChanged(ui::Window* gained_focus,
477 ui::Window* lost_focus) override {
478 if (gained_focus == mus_window())
479 platform_window_delegate()->OnActivationChanged(true);
480 else if (lost_focus == mus_window())
481 platform_window_delegate()->OnActivationChanged(false);
482 }
483 void OnRequestClose(ui::Window* window) override {
484 platform_window_delegate()->OnCloseRequest();
485 }
486
487 private:
488 ui::Window* mus_window() { return native_widget_mus_->window(); }
489 aura::Window* aura_window() { return native_widget_mus_->aura_window(); }
490 WindowTreeHostMus* window_tree_host() {
491 return native_widget_mus_->window_tree_host();
492 }
493 ui::PlatformWindowDelegate* platform_window_delegate() {
494 return native_widget_mus_->window_tree_host();
495 }
496
497 NativeWidgetMus* native_widget_mus_;
498 ui::mojom::ShowState show_state_;
499
500 DISALLOW_COPY_AND_ASSIGN(MusWindowObserver);
501 };
502
503 class NativeWidgetMus::MusCaptureClient
504 : public aura::client::DefaultCaptureClient {
505 public:
506 MusCaptureClient(aura::Window* root_window,
507 aura::Window* aura_window,
508 ui::Window* mus_window)
509 : aura::client::DefaultCaptureClient(root_window),
510 aura_window_(aura_window),
511 mus_window_(mus_window) {}
512 ~MusCaptureClient() override {}
513
514 // aura::client::DefaultCaptureClient:
515 void SetCapture(aura::Window* window) override {
516 aura::client::DefaultCaptureClient::SetCapture(window);
517 if (aura_window_ == window)
518 mus_window_->SetCapture();
519 }
520 void ReleaseCapture(aura::Window* window) override {
521 aura::client::DefaultCaptureClient::ReleaseCapture(window);
522 if (aura_window_ == window)
523 mus_window_->ReleaseCapture();
524 }
525
526 private:
527 aura::Window* aura_window_;
528 ui::Window* mus_window_;
529
530 DISALLOW_COPY_AND_ASSIGN(MusCaptureClient);
531 };
532
533 ////////////////////////////////////////////////////////////////////////////////
534 // NativeWidgetMus, public:
535
536 NativeWidgetMus::NativeWidgetMus(
537 internal::NativeWidgetDelegate* delegate,
538 ui::Window* window,
539 ui::mojom::CompositorFrameSinkType compositor_frame_sink_type)
540 : window_(window),
541 last_cursor_(ui::mojom::Cursor::CURSOR_NULL),
542 native_widget_delegate_(delegate),
543 compositor_frame_sink_type_(compositor_frame_sink_type),
544 show_state_before_fullscreen_(ui::mojom::ShowState::DEFAULT),
545 ownership_(Widget::InitParams::NATIVE_WIDGET_OWNS_WIDGET),
546 content_(new aura::Window(this)),
547 last_drop_operation_(ui::DragDropTypes::DRAG_NONE),
548 close_widget_factory_(this) {
549 window_->set_input_event_handler(this);
550 mus_window_observer_ = base::MakeUnique<MusWindowObserver>(this);
551
552 // TODO(fsamuel): Figure out lifetime of |window_|.
553 aura::SetMusWindow(content_, window_);
554 window->SetLocalProperty(kNativeWidgetMusKey, this);
555 window_tree_host_ = base::MakeUnique<WindowTreeHostMus>(this, window_);
556 input_method_ =
557 base::MakeUnique<InputMethodMus>(window_tree_host_.get(), window_);
558 window_tree_host_->SetSharedInputMethod(input_method_.get());
559 }
560
561 NativeWidgetMus::~NativeWidgetMus() {
562 if (ownership_ == Widget::InitParams::NATIVE_WIDGET_OWNS_WIDGET) {
563 DCHECK(!window_);
564 delete native_widget_delegate_;
565 } else {
566 if (window_)
567 window_->set_input_event_handler(nullptr);
568 CloseNow();
569 }
570 }
571
572 // static
573 void NativeWidgetMus::NotifyFrameChanged(ui::WindowTreeClient* client) {
574 for (ui::Window* window : client->GetRoots()) {
575 NativeWidgetMus* native_widget =
576 window->GetLocalProperty(kNativeWidgetMusKey);
577 if (native_widget && native_widget->GetWidget()->non_client_view()) {
578 native_widget->GetWidget()->non_client_view()->Layout();
579 native_widget->GetWidget()->non_client_view()->SchedulePaint();
580 native_widget->UpdateClientArea();
581 native_widget->UpdateHitTestMask();
582 }
583 }
584 }
585
586 // static
587 NativeWidgetMus* NativeWidgetMus::GetForWindow(ui::Window* window) {
588 DCHECK(window);
589 NativeWidgetMus* native_widget =
590 window->GetLocalProperty(kNativeWidgetMusKey);
591 return native_widget;
592 }
593
594 // static
595 Widget* NativeWidgetMus::GetWidgetForWindow(ui::Window* window) {
596 NativeWidgetMus* native_widget = GetForWindow(window);
597 if (!native_widget)
598 return nullptr;
599 return native_widget->GetWidget();
600 }
601
602 aura::Window* NativeWidgetMus::GetRootWindow() {
603 return window_tree_host_->window();
604 }
605
606 void NativeWidgetMus::OnPlatformWindowClosed() {
607 native_widget_delegate_->OnNativeWidgetDestroying();
608
609 tooltip_manager_.reset();
610 if (tooltip_controller_.get()) {
611 window_tree_host_->window()->RemovePreTargetHandler(
612 tooltip_controller_.get());
613 aura::client::SetTooltipClient(window_tree_host_->window(), NULL);
614 tooltip_controller_.reset();
615 }
616
617 window_parenting_client_.reset(); // Uses |content_|.
618 capture_client_.reset(); // Uses |content_|.
619
620 window_tree_host_->RemoveObserver(this);
621 window_tree_host_.reset();
622
623 cursor_manager_.reset(); // Uses |window_|.
624
625 mus_window_observer_.reset(nullptr);
626
627 window_ = nullptr;
628 content_ = nullptr;
629
630 native_widget_delegate_->OnNativeWidgetDestroyed();
631 if (ownership_ == Widget::InitParams::NATIVE_WIDGET_OWNS_WIDGET)
632 delete this;
633 }
634
635 void NativeWidgetMus::OnActivationChanged(bool active) {
636 if (!native_widget_delegate_)
637 return;
638 if (active) {
639 native_widget_delegate_->OnNativeFocus();
640 GetWidget()->GetFocusManager()->RestoreFocusedView();
641 } else {
642 native_widget_delegate_->OnNativeBlur();
643 GetWidget()->GetFocusManager()->StoreFocusedView(true);
644 }
645 native_widget_delegate_->OnNativeWidgetActivationChanged(active);
646 }
647
648 void NativeWidgetMus::UpdateClientArea() {
649 if (is_parallel_widget_in_window_manager())
650 return;
651
652 NonClientView* non_client_view =
653 native_widget_delegate_->AsWidget()->non_client_view();
654 if (!non_client_view || !non_client_view->client_view())
655 return;
656
657 const gfx::Rect client_area_rect(non_client_view->client_view()->bounds());
658 window_->SetClientArea(gfx::Insets(
659 client_area_rect.y(), client_area_rect.x(),
660 non_client_view->bounds().height() - client_area_rect.bottom(),
661 non_client_view->bounds().width() - client_area_rect.right()));
662 }
663
664 ////////////////////////////////////////////////////////////////////////////////
665 // NativeWidgetMus, private:
666
667 // static
668 void NativeWidgetMus::ConfigurePropertiesForNewWindow(
669 const Widget::InitParams& init_params,
670 std::map<std::string, std::vector<uint8_t>>* properties) {
671 properties->insert(init_params.mus_properties.begin(),
672 init_params.mus_properties.end());
673 if (!init_params.bounds.IsEmpty()) {
674 (*properties)[ui::mojom::WindowManager::kBounds_InitProperty] =
675 mojo::ConvertTo<std::vector<uint8_t>>(init_params.bounds);
676 }
677 if (!init_params.name.empty()) {
678 (*properties)[ui::mojom::WindowManager::kName_Property] =
679 mojo::ConvertTo<std::vector<uint8_t>>(init_params.name);
680 }
681 (*properties)[ui::mojom::WindowManager::kAlwaysOnTop_Property] =
682 mojo::ConvertTo<std::vector<uint8_t>>(
683 static_cast<PrimitiveType>(init_params.keep_on_top));
684
685 (*properties)[ui::mojom::WindowManager::kWindowType_InitProperty] =
686 mojo::ConvertTo<std::vector<uint8_t>>(
687 static_cast<int32_t>(init_params.type));
688
689 if (!Widget::RequiresNonClientView(init_params.type))
690 return;
691
692 if (init_params.delegate) {
693 if (properties->count(ui::mojom::WindowManager::kResizeBehavior_Property) ==
694 0) {
695 (*properties)[ui::mojom::WindowManager::kResizeBehavior_Property] =
696 mojo::ConvertTo<std::vector<uint8_t>>(static_cast<PrimitiveType>(
697 init_params.delegate->GetResizeBehavior()));
698 }
699
700 // TODO(crbug.com/667566): Support additional scales or gfx::Image[Skia].
701 gfx::ImageSkia app_icon = init_params.delegate->GetWindowAppIcon();
702 SkBitmap app_bitmap = app_icon.GetRepresentation(1.f).sk_bitmap();
703 if (!app_bitmap.isNull()) {
704 (*properties)[ui::mojom::WindowManager::kAppIcon_Property] =
705 mojo::ConvertTo<std::vector<uint8_t>>(app_bitmap);
706 }
707 // TODO(crbug.com/667566): Support additional scales or gfx::Image[Skia].
708 gfx::ImageSkia window_icon = init_params.delegate->GetWindowIcon();
709 SkBitmap window_bitmap = window_icon.GetRepresentation(1.f).sk_bitmap();
710 if (!window_bitmap.isNull()) {
711 (*properties)[ui::mojom::WindowManager::kWindowIcon_Property] =
712 mojo::ConvertTo<std::vector<uint8_t>>(window_bitmap);
713 }
714 }
715 }
716
717 ////////////////////////////////////////////////////////////////////////////////
718 // NativeWidgetMus, internal::NativeWidgetPrivate implementation:
719
720 NonClientFrameView* NativeWidgetMus::CreateNonClientFrameView() {
721 return new ClientSideNonClientFrameView(GetWidget());
722 }
723
724 void NativeWidgetMus::InitNativeWidget(const Widget::InitParams& params) {
725 NativeWidgetAura::RegisterNativeWidgetForWindow(this, content_);
726 aura::Window* hosted_window = window_tree_host_->window();
727
728 ownership_ = params.ownership;
729 window_->SetCanFocus(params.activatable ==
730 Widget::InitParams::ACTIVATABLE_YES);
731 window_->SetCanAcceptEvents(params.accept_events);
732
733 window_tree_host_->AddObserver(this);
734 window_tree_host_->InitHost();
735 window_tree_host_->window()->Show();
736 hosted_window->SetProperty(kMusWindow, window_);
737
738 // TODO(moshayedi): crbug.com/641039. Investigate whether there are any cases
739 // where we need input method but don't have the WindowManagerConnection here.
740 if (WindowManagerConnection::Exists())
741 input_method_->Init(WindowManagerConnection::Get()->connector());
742
743 focus_client_ =
744 base::MakeUnique<FocusControllerMus>(new FocusRulesImpl(hosted_window));
745
746 aura::client::SetFocusClient(hosted_window, focus_client_.get());
747 aura::client::SetActivationClient(hosted_window, focus_client_.get());
748 screen_position_client_ = base::MakeUnique<ScreenPositionClientMus>(window_);
749 aura::client::SetScreenPositionClient(hosted_window,
750 screen_position_client_.get());
751
752 drag_drop_client_ = base::MakeUnique<DragDropClientMus>(window_);
753 aura::client::SetDragDropClient(hosted_window, drag_drop_client_.get());
754 drop_target_ = base::MakeUnique<DropTargetMus>(content_);
755 window_->SetCanAcceptDrops(drop_target_.get());
756 drop_helper_ = base::MakeUnique<DropHelper>(GetWidget()->GetRootView());
757 aura::client::SetDragDropDelegate(content_, this);
758
759 if (params.type != Widget::InitParams::TYPE_TOOLTIP) {
760 tooltip_manager_ = base::MakeUnique<TooltipManagerAura>(GetWidget());
761 tooltip_controller_ = base::MakeUnique<corewm::TooltipController>(
762 base::MakeUnique<corewm::TooltipAura>());
763 aura::client::SetTooltipClient(window_tree_host_->window(),
764 tooltip_controller_.get());
765 window_tree_host_->window()->AddPreTargetHandler(tooltip_controller_.get());
766 }
767
768 // TODO(erg): Remove this check when ash/mus/move_event_handler.cc's
769 // direct usage of ui::Window::SetPredefinedCursor() is switched to a
770 // private method on WindowManagerClient.
771 if (!is_parallel_widget_in_window_manager()) {
772 cursor_manager_ = base::MakeUnique<wm::CursorManager>(
773 base::MakeUnique<NativeCursorManagerMus>(window_));
774 aura::client::SetCursorClient(hosted_window, cursor_manager_.get());
775 }
776
777 window_parenting_client_ =
778 base::MakeUnique<NativeWidgetMusWindowParentingClient>(hosted_window);
779 hosted_window->AddPreTargetHandler(focus_client_.get());
780 hosted_window->SetLayoutManager(
781 new ContentWindowLayoutManager(hosted_window, content_));
782 capture_client_ =
783 base::MakeUnique<MusCaptureClient>(hosted_window, content_, window_);
784
785 content_->SetType(ui::wm::WINDOW_TYPE_NORMAL);
786 content_->Init(params.layer_type);
787 if (window_->visible())
788 content_->Show();
789 content_->SetTransparent(true);
790 content_->SetFillsBoundsCompletely(false);
791 content_->set_ignore_events(!params.accept_events);
792 hosted_window->AddChild(content_);
793
794 ui::Window* parent_mus = params.parent_mus;
795
796 // Set-up transiency if appropriate.
797 if (params.parent && !params.child) {
798 aura::Window* parent_root_aura = params.parent->GetRootWindow();
799 ui::Window* parent_root_mus = parent_root_aura->GetProperty(kMusWindow);
800 if (parent_root_mus) {
801 parent_root_mus->AddTransientWindow(window_);
802 if (!parent_mus)
803 parent_mus = parent_root_mus;
804 }
805 }
806
807 if (parent_mus)
808 parent_mus->AddChild(window_);
809
810 // TODO(sky): deal with show state.
811 if (!params.bounds.size().IsEmpty())
812 SetBounds(params.bounds);
813
814 // TODO(beng): much else, see [Desktop]NativeWidgetAura.
815
816 native_widget_delegate_->OnNativeWidgetCreated(false);
817 }
818
819 void NativeWidgetMus::OnWidgetInitDone() {
820 // The client area is calculated from the NonClientView. During
821 // InitNativeWidget() the NonClientView has not been created. When this
822 // function is called the NonClientView has been created, so that we can
823 // correctly calculate the client area and push it to the ui::Window.
824 UpdateClientArea();
825 UpdateHitTestMask();
826 }
827
828 bool NativeWidgetMus::ShouldUseNativeFrame() const {
829 NOTIMPLEMENTED();
830 return false;
831 }
832
833 bool NativeWidgetMus::ShouldWindowContentsBeTransparent() const {
834 NOTIMPLEMENTED();
835 return true;
836 }
837
838 void NativeWidgetMus::FrameTypeChanged() {
839 NOTIMPLEMENTED();
840 }
841
842 Widget* NativeWidgetMus::GetWidget() {
843 return native_widget_delegate_->AsWidget();
844 }
845
846 const Widget* NativeWidgetMus::GetWidget() const {
847 return native_widget_delegate_->AsWidget();
848 }
849
850 gfx::NativeView NativeWidgetMus::GetNativeView() const {
851 return content_;
852 }
853
854 gfx::NativeWindow NativeWidgetMus::GetNativeWindow() const {
855 return content_;
856 }
857
858 Widget* NativeWidgetMus::GetTopLevelWidget() {
859 return GetWidget();
860 }
861
862 const ui::Compositor* NativeWidgetMus::GetCompositor() const {
863 return window_tree_host_->compositor();
864 }
865
866 const ui::Layer* NativeWidgetMus::GetLayer() const {
867 return content_ ? content_->layer() : nullptr;
868 }
869
870 void NativeWidgetMus::ReorderNativeViews() {
871 NOTIMPLEMENTED();
872 }
873
874 void NativeWidgetMus::ViewRemoved(View* view) {
875 NOTIMPLEMENTED();
876 }
877
878 // These methods are wrong in mojo. They're not usually used to associate data
879 // with a window; they are used to pass data from one layer to another (and in
880 // chrome/ to unsafely pass raw pointers around--I can only find two places
881 // where we do the "safe" thing and even that requires casting an integer to a
882 // void*). They can't be used safely in a world where we separate things with
883 // mojo.
884 //
885 // It's also used to communicate between views and aura; in views, we set
886 // properties on a widget, and read these properties directly in aura code.
887 void NativeWidgetMus::SetNativeWindowProperty(const char* name, void* value) {
888 if (content_)
889 content_->SetNativeWindowProperty(name, value);
890 }
891
892 void* NativeWidgetMus::GetNativeWindowProperty(const char* name) const {
893 return content_ ? content_->GetNativeWindowProperty(name) : nullptr;
894 }
895
896 TooltipManager* NativeWidgetMus::GetTooltipManager() const {
897 return tooltip_manager_.get();
898 }
899
900 void NativeWidgetMus::SetCapture() {
901 if (content_)
902 content_->SetCapture();
903 }
904
905 void NativeWidgetMus::ReleaseCapture() {
906 if (content_)
907 content_->ReleaseCapture();
908 }
909
910 bool NativeWidgetMus::HasCapture() const {
911 return content_ && content_->HasCapture();
912 }
913
914 ui::InputMethod* NativeWidgetMus::GetInputMethod() {
915 return window_tree_host_ ? window_tree_host_->GetInputMethod() : nullptr;
916 }
917
918 void NativeWidgetMus::CenterWindow(const gfx::Size& size) {
919 if (is_parallel_widget_in_window_manager())
920 return;
921 // TODO(beng): clear user-placed property and set preferred size property.
922 window_->SetSharedProperty<gfx::Size>(
923 ui::mojom::WindowManager::kPreferredSize_Property, size);
924
925 gfx::Rect bounds = display::Screen::GetScreen()
926 ->GetDisplayNearestWindow(content_)
927 .work_area();
928 bounds.ClampToCenteredSize(size);
929 window_->SetBounds(bounds);
930 }
931
932 void NativeWidgetMus::GetWindowPlacement(
933 gfx::Rect* bounds,
934 ui::WindowShowState* maximized) const {
935 NOTIMPLEMENTED();
936 }
937
938 bool NativeWidgetMus::SetWindowTitle(const base::string16& title) {
939 if (!window_ || is_parallel_widget_in_window_manager())
940 return false;
941 const char* kWindowTitle_Property =
942 ui::mojom::WindowManager::kWindowTitle_Property;
943 const base::string16 current_title =
944 window_->HasSharedProperty(kWindowTitle_Property)
945 ? window_->GetSharedProperty<base::string16>(kWindowTitle_Property)
946 : base::string16();
947 if (current_title == title)
948 return false;
949 window_->SetSharedProperty<base::string16>(kWindowTitle_Property, title);
950 return true;
951 }
952
953 void NativeWidgetMus::SetWindowIcons(const gfx::ImageSkia& window_icon,
954 const gfx::ImageSkia& app_icon) {
955 if (is_parallel_widget_in_window_manager())
956 return;
957
958 SetIconProperty(window_, ui::mojom::WindowManager::kWindowIcon_Property,
959 window_icon);
960 SetIconProperty(window_, ui::mojom::WindowManager::kAppIcon_Property,
961 app_icon);
962 }
963
964 void NativeWidgetMus::InitModalType(ui::ModalType modal_type) {
965 if (modal_type != ui::MODAL_TYPE_NONE)
966 window_->SetModal();
967 }
968
969 gfx::Rect NativeWidgetMus::GetWindowBoundsInScreen() const {
970 if (!window_)
971 return gfx::Rect();
972
973 // Correct for the origin of the display.
974 const int64_t window_display_id = window_->GetRoot()->display_id();
975 for (display::Display display :
976 display::Screen::GetScreen()->GetAllDisplays()) {
977 if (display.id() == window_display_id) {
978 gfx::Point display_origin = display.bounds().origin();
979 gfx::Rect bounds_in_screen = window_->GetBoundsInRoot();
980 bounds_in_screen.Offset(display_origin.x(), display_origin.y());
981 return bounds_in_screen;
982 }
983 }
984 // Unknown display, assume primary display at 0,0.
985 return window_->GetBoundsInRoot();
986 }
987
988 gfx::Rect NativeWidgetMus::GetClientAreaBoundsInScreen() const {
989 // View-to-screen coordinate system transformations depend on this returning
990 // the full window bounds, for example View::ConvertPointToScreen().
991 return GetWindowBoundsInScreen();
992 }
993
994 gfx::Rect NativeWidgetMus::GetRestoredBounds() const {
995 // Restored bounds should only be relevant if the window is minimized,
996 // maximized, fullscreen or docked. However, in some places the code expects
997 // GetRestoredBounds() to return the current window bounds if the window is
998 // not in either state.
999 if (IsMinimized() || IsMaximized() || IsFullscreen()) {
1000 const char* kRestoreBounds_Property =
1001 ui::mojom::WindowManager::kRestoreBounds_Property;
1002 if (window_->HasSharedProperty(kRestoreBounds_Property))
1003 return window_->GetSharedProperty<gfx::Rect>(kRestoreBounds_Property);
1004 }
1005 return GetWindowBoundsInScreen();
1006 }
1007
1008 std::string NativeWidgetMus::GetWorkspace() const {
1009 return std::string();
1010 }
1011
1012 void NativeWidgetMus::SetBounds(const gfx::Rect& bounds_in_screen) {
1013 if (!(window_ && window_tree_host_))
1014 return;
1015
1016 // TODO(jamescook): Needs something like aura::ScreenPositionClient so higher
1017 // level code can move windows between displays. crbug.com/645291
1018 gfx::Point origin(bounds_in_screen.origin());
1019 const gfx::Point display_origin = display::Screen::GetScreen()
1020 ->GetDisplayMatching(bounds_in_screen)
1021 .bounds()
1022 .origin();
1023 origin.Offset(-display_origin.x(), -display_origin.y());
1024
1025 gfx::Size size(bounds_in_screen.size());
1026 const gfx::Size min_size = GetMinimumSize();
1027 const gfx::Size max_size = GetMaximumSize();
1028 if (!max_size.IsEmpty())
1029 size.SetToMin(max_size);
1030 size.SetToMax(min_size);
1031 window_->SetBounds(gfx::Rect(origin, size));
1032 // Observer on |window_tree_host_| expected to synchronously update bounds.
1033 DCHECK_EQ(gfx::ConvertRectToPixel(ScaleFactorForDisplay(content_),
1034 window_->bounds())
1035 .ToString(),
1036 window_tree_host_->GetBoundsInPixels().ToString());
1037 }
1038
1039 void NativeWidgetMus::SetSize(const gfx::Size& size) {
1040 if (!window_tree_host_)
1041 return;
1042
1043 gfx::Rect bounds = window_tree_host_->GetBoundsInPixels();
1044 SetBounds(gfx::Rect(bounds.origin(), size));
1045 }
1046
1047 void NativeWidgetMus::StackAbove(gfx::NativeView native_view) {
1048 NOTIMPLEMENTED();
1049 }
1050
1051 void NativeWidgetMus::StackAtTop() {
1052 NOTIMPLEMENTED();
1053 }
1054
1055 void NativeWidgetMus::SetShape(std::unique_ptr<SkRegion> shape) {
1056 NOTIMPLEMENTED();
1057 }
1058
1059 void NativeWidgetMus::Close() {
1060 Hide();
1061 if (!close_widget_factory_.HasWeakPtrs()) {
1062 base::ThreadTaskRunnerHandle::Get()->PostTask(
1063 FROM_HERE, base::Bind(&NativeWidgetMus::CloseNow,
1064 close_widget_factory_.GetWeakPtr()));
1065 }
1066 }
1067
1068 void NativeWidgetMus::CloseNow() {
1069 // Depending upon ownership |window_| may have been destroyed.
1070 if (window_)
1071 window_->Destroy();
1072 }
1073
1074 void NativeWidgetMus::Show() {
1075 ShowWithWindowState(ui::SHOW_STATE_NORMAL);
1076 }
1077
1078 void NativeWidgetMus::Hide() {
1079 if (!(window_ && window_tree_host_))
1080 return;
1081
1082 // NOTE: |window_tree_host_| and |window_| visibility is updated in
1083 // OnMusWindowVisibilityChanged().
1084 window_->SetVisible(false);
1085 }
1086
1087 void NativeWidgetMus::ShowMaximizedWithBounds(
1088 const gfx::Rect& restored_bounds) {
1089 if (!window_)
1090 return;
1091
1092 window_->SetSharedProperty<gfx::Rect>(
1093 ui::mojom::WindowManager::kRestoreBounds_Property, restored_bounds);
1094 ShowWithWindowState(ui::SHOW_STATE_MAXIMIZED);
1095 }
1096
1097 void NativeWidgetMus::ShowWithWindowState(ui::WindowShowState state) {
1098 if (!(window_ && window_tree_host_))
1099 return;
1100
1101 // Matches NativeWidgetAura.
1102 switch (state) {
1103 case ui::SHOW_STATE_MAXIMIZED:
1104 SetShowState(ui::mojom::ShowState::MAXIMIZED);
1105 break;
1106 case ui::SHOW_STATE_FULLSCREEN:
1107 SetShowState(ui::mojom::ShowState::FULLSCREEN);
1108 break;
1109 case ui::SHOW_STATE_DOCKED:
1110 SetShowState(ui::mojom::ShowState::DOCKED);
1111 break;
1112 default:
1113 break;
1114 }
1115
1116 // NOTE: |window_tree_host_| and |window_| visibility is updated in
1117 // OnMusWindowVisibilityChanged().
1118 window_->SetVisible(true);
1119 if (native_widget_delegate_->CanActivate()) {
1120 if (state != ui::SHOW_STATE_INACTIVE)
1121 Activate();
1122 GetWidget()->SetInitialFocus(state);
1123 }
1124
1125 // Matches NativeWidgetAura.
1126 if (state == ui::SHOW_STATE_MINIMIZED)
1127 Minimize();
1128 }
1129
1130 bool NativeWidgetMus::IsVisible() const {
1131 // TODO(beng): this should probably be wired thru PlatformWindow.
1132 return window_ && window_->visible();
1133 }
1134
1135 void NativeWidgetMus::Activate() {
1136 if (!window_)
1137 return;
1138
1139 static_cast<aura::client::ActivationClient*>(focus_client_.get())
1140 ->ActivateWindow(content_);
1141 }
1142
1143 void NativeWidgetMus::Deactivate() {
1144 if (IsActive())
1145 window_->window_tree()->ClearFocus();
1146 }
1147
1148 bool NativeWidgetMus::IsActive() const {
1149 ui::Window* focused =
1150 window_ ? window_->window_tree()->GetFocusedWindow() : nullptr;
1151 return focused && window_->Contains(focused);
1152 }
1153
1154 void NativeWidgetMus::SetAlwaysOnTop(bool always_on_top) {
1155 if (window_ && !is_parallel_widget_in_window_manager()) {
1156 window_->SetSharedProperty<bool>(
1157 ui::mojom::WindowManager::kAlwaysOnTop_Property, always_on_top);
1158 }
1159 }
1160
1161 bool NativeWidgetMus::IsAlwaysOnTop() const {
1162 return window_ &&
1163 window_->HasSharedProperty(
1164 ui::mojom::WindowManager::kAlwaysOnTop_Property) &&
1165 window_->GetSharedProperty<bool>(
1166 ui::mojom::WindowManager::kAlwaysOnTop_Property);
1167 }
1168
1169 void NativeWidgetMus::SetVisibleOnAllWorkspaces(bool always_visible) {
1170 // Not needed for chromeos.
1171 }
1172
1173 bool NativeWidgetMus::IsVisibleOnAllWorkspaces() const {
1174 return false;
1175 }
1176
1177 void NativeWidgetMus::Maximize() {
1178 SetShowState(ui::mojom::ShowState::MAXIMIZED);
1179 }
1180
1181 void NativeWidgetMus::Minimize() {
1182 SetShowState(ui::mojom::ShowState::MINIMIZED);
1183 }
1184
1185 bool NativeWidgetMus::IsMaximized() const {
1186 return GetShowState(window_) == ui::mojom::ShowState::MAXIMIZED;
1187 }
1188
1189 bool NativeWidgetMus::IsMinimized() const {
1190 return GetShowState(window_) == ui::mojom::ShowState::MINIMIZED;
1191 }
1192
1193 void NativeWidgetMus::Restore() {
1194 SetShowState(ui::mojom::ShowState::NORMAL);
1195 }
1196
1197 void NativeWidgetMus::SetFullscreen(bool fullscreen) {
1198 if (IsFullscreen() == fullscreen)
1199 return;
1200 if (fullscreen) {
1201 show_state_before_fullscreen_ = GetShowState(window_);
1202 SetShowState(ui::mojom::ShowState::FULLSCREEN);
1203 } else {
1204 switch (show_state_before_fullscreen_) {
1205 case ui::mojom::ShowState::MAXIMIZED:
1206 Maximize();
1207 break;
1208 case ui::mojom::ShowState::MINIMIZED:
1209 Minimize();
1210 break;
1211 case ui::mojom::ShowState::DEFAULT:
1212 case ui::mojom::ShowState::NORMAL:
1213 case ui::mojom::ShowState::INACTIVE:
1214 case ui::mojom::ShowState::FULLSCREEN:
1215 case ui::mojom::ShowState::DOCKED:
1216 // TODO(sad): This may not be sufficient.
1217 Restore();
1218 break;
1219 }
1220 }
1221 }
1222
1223 bool NativeWidgetMus::IsFullscreen() const {
1224 return GetShowState(window_) == ui::mojom::ShowState::FULLSCREEN;
1225 }
1226
1227 void NativeWidgetMus::SetOpacity(float opacity) {
1228 if (window_)
1229 window_->SetOpacity(opacity);
1230 }
1231
1232 void NativeWidgetMus::FlashFrame(bool flash_frame) {
1233 NOTIMPLEMENTED();
1234 }
1235
1236 void NativeWidgetMus::RunShellDrag(View* view,
1237 const ui::OSExchangeData& data,
1238 const gfx::Point& location,
1239 int drag_operations,
1240 ui::DragDropTypes::DragEventSource source) {
1241 if (window_)
1242 views::RunShellDrag(content_, data, location, drag_operations, source);
1243 }
1244
1245 void NativeWidgetMus::SchedulePaintInRect(const gfx::Rect& rect) {
1246 if (content_)
1247 content_->SchedulePaintInRect(rect);
1248 }
1249
1250 void NativeWidgetMus::SetCursor(gfx::NativeCursor cursor) {
1251 if (!window_)
1252 return;
1253
1254 // TODO(erg): In aura, our incoming cursor is really two
1255 // parts. cursor.native_type() is an integer for standard cursors and is all
1256 // we support right now. If native_type() == kCursorCustom, than we should
1257 // also send an image, but as the cursor code is currently written, the image
1258 // is in a platform native format that's already uploaded to the window
1259 // server.
1260 ui::mojom::Cursor new_cursor = ui::mojom::Cursor(cursor.native_type());
1261 if (last_cursor_ != new_cursor)
1262 window_->SetPredefinedCursor(new_cursor);
1263 }
1264
1265 bool NativeWidgetMus::IsMouseEventsEnabled() const {
1266 NOTIMPLEMENTED();
1267 return true;
1268 }
1269
1270 void NativeWidgetMus::ClearNativeFocus() {
1271 if (!IsActive())
1272 return;
1273 ui::Window* focused =
1274 window_ ? window_->window_tree()->GetFocusedWindow() : nullptr;
1275 if (focused && window_->Contains(focused) && focused != window_)
1276 window_->SetFocus();
1277 // Move aura-focus back to |content_|, so that the Widget still receives
1278 // events correctly.
1279 aura::client::GetFocusClient(content_)->ResetFocusWithinActiveWindow(
1280 content_);
1281 }
1282
1283 gfx::Rect NativeWidgetMus::GetWorkAreaBoundsInScreen() const {
1284 NOTIMPLEMENTED();
1285 return gfx::Rect();
1286 }
1287
1288 Widget::MoveLoopResult NativeWidgetMus::RunMoveLoop(
1289 const gfx::Vector2d& drag_offset,
1290 Widget::MoveLoopSource source,
1291 Widget::MoveLoopEscapeBehavior escape_behavior) {
1292 ReleaseCapture();
1293
1294 base::MessageLoopForUI* loop = base::MessageLoopForUI::current();
1295 base::MessageLoop::ScopedNestableTaskAllower allow_nested(loop);
1296 base::RunLoop run_loop;
1297
1298 ui::mojom::MoveLoopSource mus_source =
1299 source == Widget::MOVE_LOOP_SOURCE_MOUSE
1300 ? ui::mojom::MoveLoopSource::MOUSE
1301 : ui::mojom::MoveLoopSource::TOUCH;
1302
1303 bool success = false;
1304 gfx::Point cursor_location =
1305 display::Screen::GetScreen()->GetCursorScreenPoint();
1306 window_->PerformWindowMove(
1307 mus_source, cursor_location,
1308 base::Bind(OnMoveLoopEnd, &success, run_loop.QuitClosure()));
1309
1310 run_loop.Run();
1311
1312 return success ? Widget::MOVE_LOOP_SUCCESSFUL : Widget::MOVE_LOOP_CANCELED;
1313 }
1314
1315 void NativeWidgetMus::EndMoveLoop() {
1316 window_->CancelWindowMove();
1317 }
1318
1319 void NativeWidgetMus::SetVisibilityChangedAnimationsEnabled(bool value) {
1320 NOTIMPLEMENTED();
1321 }
1322
1323 void NativeWidgetMus::SetVisibilityAnimationDuration(
1324 const base::TimeDelta& duration) {
1325 NOTIMPLEMENTED();
1326 }
1327
1328 void NativeWidgetMus::SetVisibilityAnimationTransition(
1329 Widget::VisibilityTransition transition) {
1330 NOTIMPLEMENTED();
1331 }
1332
1333 bool NativeWidgetMus::IsTranslucentWindowOpacitySupported() const {
1334 NOTIMPLEMENTED();
1335 return true;
1336 }
1337
1338 void NativeWidgetMus::OnSizeConstraintsChanged() {
1339 if (!window_ || is_parallel_widget_in_window_manager())
1340 return;
1341
1342 int32_t behavior = ui::mojom::kResizeBehaviorNone;
1343 if (GetWidget()->widget_delegate())
1344 behavior = GetWidget()->widget_delegate()->GetResizeBehavior();
1345 window_->SetSharedProperty<PrimitiveType>(
1346 ui::mojom::WindowManager::kResizeBehavior_Property, behavior);
1347 }
1348
1349 void NativeWidgetMus::RepostNativeEvent(gfx::NativeEvent native_event) {
1350 NOTIMPLEMENTED();
1351 }
1352
1353 std::string NativeWidgetMus::GetName() const {
1354 return window_->GetName();
1355 }
1356
1357 ////////////////////////////////////////////////////////////////////////////////
1358 // NativeWidgetMus, aura::WindowDelegate implementation:
1359
1360 gfx::Size NativeWidgetMus::GetMinimumSize() const {
1361 return native_widget_delegate_->GetMinimumSize();
1362 }
1363
1364 gfx::Size NativeWidgetMus::GetMaximumSize() const {
1365 return native_widget_delegate_->GetMaximumSize();
1366 }
1367
1368 void NativeWidgetMus::OnBoundsChanged(const gfx::Rect& old_bounds,
1369 const gfx::Rect& new_bounds) {
1370 // This is handled in OnHost{Resized,Moved}() like DesktopNativeWidgetAura
1371 // instead of here like in NativeWidgetAura.
1372 }
1373
1374 gfx::NativeCursor NativeWidgetMus::GetCursor(const gfx::Point& point) {
1375 return gfx::NativeCursor();
1376 }
1377
1378 int NativeWidgetMus::GetNonClientComponent(const gfx::Point& point) const {
1379 return native_widget_delegate_->GetNonClientComponent(point);
1380 }
1381
1382 bool NativeWidgetMus::ShouldDescendIntoChildForEventHandling(
1383 aura::Window* child,
1384 const gfx::Point& location) {
1385 views::WidgetDelegate* widget_delegate = GetWidget()->widget_delegate();
1386 return !widget_delegate ||
1387 widget_delegate->ShouldDescendIntoChildForEventHandling(child, location);
1388 }
1389
1390 bool NativeWidgetMus::CanFocus() {
1391 return true;
1392 }
1393
1394 void NativeWidgetMus::OnCaptureLost() {
1395 native_widget_delegate_->OnMouseCaptureLost();
1396 }
1397
1398 void NativeWidgetMus::OnPaint(const ui::PaintContext& context) {
1399 native_widget_delegate_->OnNativeWidgetPaint(context);
1400 }
1401
1402 void NativeWidgetMus::OnDeviceScaleFactorChanged(float device_scale_factor) {
1403 }
1404
1405 void NativeWidgetMus::OnWindowDestroying(aura::Window* window) {
1406 }
1407
1408 void NativeWidgetMus::OnWindowDestroyed(aura::Window* window) {
1409 // Cleanup happens in OnPlatformWindowClosed().
1410 }
1411
1412 void NativeWidgetMus::OnWindowTargetVisibilityChanged(bool visible) {
1413 }
1414
1415 bool NativeWidgetMus::HasHitTestMask() const {
1416 return native_widget_delegate_->HasHitTestMask();
1417 }
1418
1419 void NativeWidgetMus::GetHitTestMask(gfx::Path* mask) const {
1420 native_widget_delegate_->GetHitTestMask(mask);
1421 }
1422
1423 void NativeWidgetMus::SetShowState(ui::mojom::ShowState show_state) {
1424 if (!window_)
1425 return;
1426 window_->SetSharedProperty<PrimitiveType>(
1427 ui::mojom::WindowManager::kShowState_Property,
1428 static_cast<PrimitiveType>(show_state));
1429 }
1430
1431 void NativeWidgetMus::OnKeyEvent(ui::KeyEvent* event) {
1432 if (event->is_char()) {
1433 // If a ui::InputMethod object is attached to the root window, character
1434 // events are handled inside the object and are not passed to this function.
1435 // If such object is not attached, character events might be sent (e.g. on
1436 // Windows). In this case, we just skip these.
1437 return;
1438 }
1439 // Renderer may send a key event back to us if the key event wasn't handled,
1440 // and the window may be invisible by that time.
1441 if (!content_->IsVisible())
1442 return;
1443
1444 native_widget_delegate_->OnKeyEvent(event);
1445 }
1446
1447 void NativeWidgetMus::OnMouseEvent(ui::MouseEvent* event) {
1448 DCHECK(content_->IsVisible());
1449
1450 if (tooltip_manager_.get())
1451 tooltip_manager_->UpdateTooltip();
1452 TooltipManagerAura::UpdateTooltipManagerForCapture(GetWidget());
1453
1454 native_widget_delegate_->OnMouseEvent(event);
1455 // WARNING: we may have been deleted.
1456 }
1457
1458 void NativeWidgetMus::OnScrollEvent(ui::ScrollEvent* event) {
1459 if (event->type() == ui::ET_SCROLL) {
1460 native_widget_delegate_->OnScrollEvent(event);
1461 if (event->handled())
1462 return;
1463
1464 // Convert unprocessed scroll events into wheel events.
1465 ui::MouseWheelEvent mwe(*event->AsScrollEvent());
1466 native_widget_delegate_->OnMouseEvent(&mwe);
1467 if (mwe.handled())
1468 event->SetHandled();
1469 } else {
1470 native_widget_delegate_->OnScrollEvent(event);
1471 }
1472 }
1473
1474 void NativeWidgetMus::OnGestureEvent(ui::GestureEvent* event) {
1475 native_widget_delegate_->OnGestureEvent(event);
1476 }
1477
1478 void NativeWidgetMus::OnHostResized(const aura::WindowTreeHost* host) {
1479 native_widget_delegate_->OnNativeWidgetSizeChanged(
1480 host->window()->bounds().size());
1481 UpdateClientArea();
1482 UpdateHitTestMask();
1483 }
1484
1485 void NativeWidgetMus::OnHostMovedInPixels(
1486 const aura::WindowTreeHost* host,
1487 const gfx::Point& new_origin_in_pixels) {
1488 native_widget_delegate_->OnNativeWidgetMove();
1489 }
1490
1491 void NativeWidgetMus::OnHostCloseRequested(const aura::WindowTreeHost* host) {
1492 GetWidget()->Close();
1493 }
1494
1495 ////////////////////////////////////////////////////////////////////////////////
1496 // NativeWidgetMus, aura::WindowDragDropDelegate implementation:
1497
1498 void NativeWidgetMus::OnDragEntered(const ui::DropTargetEvent& event) {
1499 DCHECK(drop_helper_);
1500 last_drop_operation_ = drop_helper_->OnDragOver(
1501 event.data(), event.location(), event.source_operations());
1502 }
1503
1504 int NativeWidgetMus::OnDragUpdated(const ui::DropTargetEvent& event) {
1505 DCHECK(drop_helper_);
1506 last_drop_operation_ = drop_helper_->OnDragOver(
1507 event.data(), event.location(), event.source_operations());
1508 return last_drop_operation_;
1509 }
1510
1511 void NativeWidgetMus::OnDragExited() {
1512 DCHECK(drop_helper_);
1513 drop_helper_->OnDragExit();
1514 }
1515
1516 int NativeWidgetMus::OnPerformDrop(const ui::DropTargetEvent& event) {
1517 DCHECK(drop_helper_);
1518 return drop_helper_->OnDrop(event.data(), event.location(),
1519 last_drop_operation_);
1520 }
1521
1522 ////////////////////////////////////////////////////////////////////////////////
1523 // NativeWidgetMus, ui::InputEventHandler implementation:
1524
1525 void NativeWidgetMus::OnWindowInputEvent(
1526 ui::Window* view,
1527 const ui::Event& event_in,
1528 std::unique_ptr<base::Callback<void(EventResult)>>* ack_callback) {
1529 std::unique_ptr<ui::Event> event = ui::Event::Clone(event_in);
1530
1531 if (event->IsKeyEvent()) {
1532 input_method_->DispatchKeyEvent(event->AsKeyEvent(),
1533 std::move(*ack_callback));
1534 return;
1535 }
1536
1537 // Take ownership of the callback, indicating that we will handle it.
1538 EventAckHandler ack_handler(std::move(*ack_callback));
1539
1540 // TODO(markdittmer): This should be this->OnEvent(event.get()), but that
1541 // can't happen until IME is refactored out of in WindowTreeHostMus.
1542 platform_window_delegate()->DispatchEvent(event.get());
1543 // NOTE: |this| may be deleted.
1544
1545 ack_handler.set_handled(event->handled());
1546 // |ack_handler| acks the event on destruction if necessary.
1547 }
1548
1549 void NativeWidgetMus::OnMusWindowVisibilityChanging(ui::Window* window,
1550 bool visible) {
1551 if (window == window_)
1552 native_widget_delegate_->OnNativeWidgetVisibilityChanging(visible);
1553 }
1554
1555 void NativeWidgetMus::OnMusWindowVisibilityChanged(ui::Window* window,
1556 bool visible) {
1557 if (window != window_)
1558 return;
1559
1560 if (visible) {
1561 window_tree_host_->Show();
1562 GetNativeWindow()->Show();
1563 } else {
1564 window_tree_host_->Hide();
1565 GetNativeWindow()->Hide();
1566 }
1567 native_widget_delegate_->OnNativeWidgetVisibilityChanged(visible);
1568 }
1569
1570 void NativeWidgetMus::UpdateHitTestMask() {
1571 // The window manager (or other underlay window provider) is not allowed to
1572 // set a hit test mask, as that could interfere with a client app mask.
1573 if (is_parallel_widget_in_window_manager())
1574 return;
1575
1576 if (!native_widget_delegate_->HasHitTestMask()) {
1577 window_->ClearHitTestMask();
1578 return;
1579 }
1580
1581 gfx::Path mask_path;
1582 native_widget_delegate_->GetHitTestMask(&mask_path);
1583 // TODO(jamescook): Use the full path for the mask.
1584 gfx::Rect mask_rect =
1585 gfx::ToEnclosingRect(gfx::SkRectToRectF(mask_path.getBounds()));
1586 window_->SetHitTestMask(mask_rect);
1587 }
1588
1589 } // namespace views
OLDNEW
« no previous file with comments | « ui/views/mus/native_widget_mus.h ('k') | ui/views/mus/native_widget_mus_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698