| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "components/exo/shell_surface.h" | 5 #include "components/exo/shell_surface.h" |
| 6 | 6 |
| 7 #include "ash/aura/wm_window_aura.h" | 7 #include "ash/aura/wm_window_aura.h" |
| 8 #include "ash/common/shell_window_ids.h" | 8 #include "ash/common/shell_window_ids.h" |
| 9 #include "ash/common/wm/window_resizer.h" | 9 #include "ash/common/wm/window_resizer.h" |
| 10 #include "ash/common/wm/window_state.h" | 10 #include "ash/common/wm/window_state.h" |
| (...skipping 359 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 370 | 370 |
| 371 void ShellSurface::SetTitle(const base::string16& title) { | 371 void ShellSurface::SetTitle(const base::string16& title) { |
| 372 TRACE_EVENT1("exo", "ShellSurface::SetTitle", "title", | 372 TRACE_EVENT1("exo", "ShellSurface::SetTitle", "title", |
| 373 base::UTF16ToUTF8(title)); | 373 base::UTF16ToUTF8(title)); |
| 374 | 374 |
| 375 title_ = title; | 375 title_ = title; |
| 376 if (widget_) | 376 if (widget_) |
| 377 widget_->UpdateWindowTitle(); | 377 widget_->UpdateWindowTitle(); |
| 378 } | 378 } |
| 379 | 379 |
| 380 void ShellSurface::SetSystemModal(bool system_modal) { | |
| 381 // System modal container is used by clients to implement client side | |
| 382 // managed system modal dialogs using a single ShellSurface instance. | |
| 383 // Hit-test region will be non-empty when at least one dialog exists on | |
| 384 // the client side. Here we detect the transition between no client side | |
| 385 // dialog and at least one dialog so activatable state is properly | |
| 386 // updated. | |
| 387 if (container_ != ash::kShellWindowId_SystemModalContainer) { | |
| 388 LOG(ERROR) | |
| 389 << "Only a window in SystemModalContainer can change the modality"; | |
| 390 return; | |
| 391 } | |
| 392 widget_->GetNativeWindow()->SetProperty( | |
| 393 aura::client::kModalKey, | |
| 394 system_modal ? ui::MODAL_TYPE_SYSTEM : ui::MODAL_TYPE_NONE); | |
| 395 } | |
| 396 | |
| 397 // static | 380 // static |
| 398 void ShellSurface::SetApplicationId(aura::Window* window, | 381 void ShellSurface::SetApplicationId(aura::Window* window, |
| 399 std::string* application_id) { | 382 std::string* application_id) { |
| 400 window->SetProperty(kApplicationIdKey, application_id); | 383 window->SetProperty(kApplicationIdKey, application_id); |
| 401 } | 384 } |
| 402 | 385 |
| 403 // static | 386 // static |
| 404 const std::string ShellSurface::GetApplicationId(aura::Window* window) { | 387 const std::string ShellSurface::GetApplicationId(aura::Window* window) { |
| 405 std::string* string_ptr = window->GetProperty(kApplicationIdKey); | 388 std::string* string_ptr = window->GetProperty(kApplicationIdKey); |
| 406 return string_ptr ? *string_ptr : std::string(); | 389 return string_ptr ? *string_ptr : std::string(); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 438 | 421 |
| 439 if (geometry.IsEmpty()) { | 422 if (geometry.IsEmpty()) { |
| 440 DLOG(WARNING) << "Surface geometry must be non-empty"; | 423 DLOG(WARNING) << "Surface geometry must be non-empty"; |
| 441 return; | 424 return; |
| 442 } | 425 } |
| 443 | 426 |
| 444 pending_geometry_ = geometry; | 427 pending_geometry_ = geometry; |
| 445 } | 428 } |
| 446 | 429 |
| 447 void ShellSurface::SetRectangularShadow(const gfx::Rect& content_bounds) { | 430 void ShellSurface::SetRectangularShadow(const gfx::Rect& content_bounds) { |
| 448 TRACE_EVENT1("exo", "ShellSurface::SetRectangularShadow", "content_bounds", | 431 TRACE_EVENT1("exo", "ShellSurface::SetRectangularRect", "content_bounds", |
| 449 content_bounds.ToString()); | 432 content_bounds.ToString()); |
| 450 | 433 |
| 451 shadow_content_bounds_ = content_bounds; | 434 shadow_content_bounds_ = content_bounds; |
| 452 } | 435 } |
| 453 | 436 |
| 454 void ShellSurface::SetScale(double scale) { | 437 void ShellSurface::SetScale(double scale) { |
| 455 TRACE_EVENT1("exo", "ShellSurface::SetScale", "scale", scale); | 438 TRACE_EVENT1("exo", "ShellSurface::SetScale", "scale", scale); |
| 456 | 439 |
| 457 if (scale <= 0.0) { | 440 if (scale <= 0.0) { |
| 458 DLOG(WARNING) << "Surface scale must be greater than 0"; | 441 DLOG(WARNING) << "Surface scale must be greater than 0"; |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 514 | 497 |
| 515 // Apply new top inset height. | 498 // Apply new top inset height. |
| 516 if (pending_top_inset_height_ != top_inset_height_) { | 499 if (pending_top_inset_height_ != top_inset_height_) { |
| 517 widget_->GetNativeWindow()->SetProperty(aura::client::kTopViewInset, | 500 widget_->GetNativeWindow()->SetProperty(aura::client::kTopViewInset, |
| 518 pending_top_inset_height_); | 501 pending_top_inset_height_); |
| 519 top_inset_height_ = pending_top_inset_height_; | 502 top_inset_height_ = pending_top_inset_height_; |
| 520 } | 503 } |
| 521 | 504 |
| 522 gfx::Point surface_origin = GetSurfaceOrigin(); | 505 gfx::Point surface_origin = GetSurfaceOrigin(); |
| 523 | 506 |
| 524 // System modal container is used by clients to implement overlay | 507 // System modal container is used by clients to implement client side |
| 525 // windows using a single ShellSurface instance. If hit-test | 508 // managed system modal dialogs using a single ShellSurface instance. |
| 526 // region is empty, then it is non interactive window and won't be | 509 // Hit-test region will be non-empty when at least one dialog exists on |
| 527 // activated. | 510 // the client side. Here we detect the transition between no client side |
| 511 // dialog and at least one dialog so activatable state is properly |
| 512 // updated. |
| 528 if (container_ == ash::kShellWindowId_SystemModalContainer) { | 513 if (container_ == ash::kShellWindowId_SystemModalContainer) { |
| 529 gfx::Rect hit_test_bounds = | 514 gfx::Rect hit_test_bounds = |
| 530 surface_->GetHitTestBounds() + surface_origin.OffsetFromOrigin(); | 515 surface_->GetHitTestBounds() + surface_origin.OffsetFromOrigin(); |
| 531 | 516 |
| 532 // Prevent window from being activated when hit test bounds are empty. | 517 // Prevent window from being activated when hit test bounds are empty. |
| 533 bool activatable = activatable_ && !hit_test_bounds.IsEmpty(); | 518 bool activatable = activatable_ && !hit_test_bounds.IsEmpty(); |
| 534 if (activatable != CanActivate()) { | 519 if (activatable != CanActivate()) { |
| 535 set_can_activate(activatable); | 520 set_can_activate(activatable); |
| 521 widget_->GetNativeWindow()->SetProperty( |
| 522 aura::client::kModalKey, |
| 523 activatable ? ui::MODAL_TYPE_SYSTEM : ui::MODAL_TYPE_NONE); |
| 524 |
| 536 // Activate or deactivate window if activation state changed. | 525 // Activate or deactivate window if activation state changed. |
| 537 if (activatable) | 526 if (activatable) |
| 538 wm::ActivateWindow(widget_->GetNativeWindow()); | 527 wm::ActivateWindow(widget_->GetNativeWindow()); |
| 539 else if (widget_->IsActive()) | 528 else if (widget_->IsActive()) |
| 540 wm::DeactivateWindow(widget_->GetNativeWindow()); | 529 wm::DeactivateWindow(widget_->GetNativeWindow()); |
| 541 } | 530 } |
| 542 } | 531 } |
| 543 | 532 |
| 544 // Update surface bounds. | 533 // Update surface bounds. |
| 545 surface_->window()->SetBounds( | 534 surface_->window()->SetBounds( |
| (...skipping 585 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1131 } | 1120 } |
| 1132 | 1121 |
| 1133 void ShellSurface::UpdateShadow() { | 1122 void ShellSurface::UpdateShadow() { |
| 1134 if (!widget_) | 1123 if (!widget_) |
| 1135 return; | 1124 return; |
| 1136 aura::Window* window = widget_->GetNativeWindow(); | 1125 aura::Window* window = widget_->GetNativeWindow(); |
| 1137 wm::Shadow* shadow = wm::ShadowController::GetShadowForWindow(window); | 1126 wm::Shadow* shadow = wm::ShadowController::GetShadowForWindow(window); |
| 1138 if (shadow) { | 1127 if (shadow) { |
| 1139 if (shadow_content_bounds_.IsEmpty()) { | 1128 if (shadow_content_bounds_.IsEmpty()) { |
| 1140 wm::SetShadowType(window, wm::SHADOW_TYPE_NONE); | 1129 wm::SetShadowType(window, wm::SHADOW_TYPE_NONE); |
| 1141 if (shadow_underlay_) | |
| 1142 shadow_underlay_->Hide(); | |
| 1143 } else { | 1130 } else { |
| 1144 if (!shadow_overlay_) { | 1131 if (!shadow_overlay_) { |
| 1145 shadow_overlay_ = new aura::Window(nullptr); | 1132 shadow_overlay_ = new aura::Window(nullptr); |
| 1146 DCHECK(shadow_overlay_->owned_by_parent()); | 1133 DCHECK(shadow_overlay_->owned_by_parent()); |
| 1147 shadow_overlay_->set_ignore_events(true); | 1134 shadow_overlay_->set_ignore_events(true); |
| 1148 shadow_overlay_->Init(ui::LAYER_NOT_DRAWN); | 1135 shadow_overlay_->Init(ui::LAYER_NOT_DRAWN); |
| 1149 shadow_overlay_->layer()->Add(shadow->layer()); | 1136 shadow_overlay_->layer()->Add(shadow->layer()); |
| 1150 window->AddChild(shadow_overlay_); | 1137 window->AddChild(shadow_overlay_); |
| 1151 shadow_overlay_->Show(); | 1138 shadow_overlay_->Show(); |
| 1152 } | 1139 } |
| 1153 if (!shadow_underlay_) { | 1140 if (!shadow_underlay_) { |
| 1154 shadow_underlay_ = new aura::Window(nullptr); | 1141 shadow_underlay_ = new aura::Window(nullptr); |
| 1155 DCHECK(shadow_underlay_->owned_by_parent()); | 1142 DCHECK(shadow_underlay_->owned_by_parent()); |
| 1156 shadow_underlay_->set_ignore_events(true); | 1143 shadow_underlay_->set_ignore_events(true); |
| 1157 // Ensure the background area inside the shadow is solid black. | 1144 // Ensure the background area inside the shadow is solid black. |
| 1158 // Clients that provide translucent contents should not be using | 1145 // Clients that provide translucent contents should not be using |
| 1159 // rectangular shadows as this method requires opaque contents to | 1146 // rectangular shadows as this method requires opaque contents to |
| 1160 // cast a shadow that represent it correctly. | 1147 // cast a shadow that represent it correctly. |
| 1161 shadow_underlay_->Init(ui::LAYER_SOLID_COLOR); | 1148 shadow_underlay_->Init(ui::LAYER_SOLID_COLOR); |
| 1162 shadow_underlay_->layer()->SetColor(SK_ColorBLACK); | 1149 shadow_underlay_->layer()->SetColor(SK_ColorBLACK); |
| 1163 DCHECK(shadow_underlay_->layer()->fills_bounds_opaquely()); | 1150 DCHECK(shadow_underlay_->layer()->fills_bounds_opaquely()); |
| 1164 window->AddChild(shadow_underlay_); | 1151 window->AddChild(shadow_underlay_); |
| 1165 window->StackChildAtBottom(shadow_underlay_); | 1152 window->StackChildAtBottom(shadow_underlay_); |
| 1153 shadow_underlay_->Show(); |
| 1166 } | 1154 } |
| 1167 shadow_underlay_->Show(); | |
| 1168 gfx::Rect shadow_bounds(shadow_content_bounds_); | 1155 gfx::Rect shadow_bounds(shadow_content_bounds_); |
| 1169 aura::Window::ConvertRectToTarget(window->parent(), window, | 1156 aura::Window::ConvertRectToTarget(window->parent(), window, |
| 1170 &shadow_bounds); | 1157 &shadow_bounds); |
| 1171 shadow_overlay_->SetBounds(shadow_bounds); | 1158 shadow_overlay_->SetBounds(shadow_bounds); |
| 1172 shadow_underlay_->SetBounds(shadow_bounds); | 1159 shadow_underlay_->SetBounds(shadow_bounds); |
| 1173 shadow->SetContentBounds(gfx::Rect(shadow_bounds.size())); | 1160 shadow->SetContentBounds(gfx::Rect(shadow_bounds.size())); |
| 1174 wm::SetShadowType(window, wm::SHADOW_TYPE_RECTANGULAR); | 1161 wm::SetShadowType(window, wm::SHADOW_TYPE_RECTANGULAR); |
| 1175 } | 1162 } |
| 1176 } | 1163 } |
| 1177 } | 1164 } |
| 1178 | 1165 |
| 1179 } // namespace exo | 1166 } // namespace exo |
| OLD | NEW |