| OLD | NEW |
| (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 | |
| OLD | NEW |