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

Side by Side Diff: components/exo/shell_surface.cc

Issue 2706543002: exo: Synchronize multi-display window positioning (Closed)
Patch Set: Created 3 years, 10 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 | « components/exo/shell_surface.h ('k') | components/exo/shell_surface_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
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 <algorithm> 7 #include <algorithm>
8 8
9 #include "ash/common/frame/custom_frame_view_ash.h" 9 #include "ash/common/frame/custom_frame_view_ash.h"
10 #include "ash/common/shelf/wm_shelf.h" 10 #include "ash/common/shelf/wm_shelf.h"
(...skipping 351 matching lines...) Expand 10 before | Expand all | Expand 10 after
362 // Commit() is called. 362 // Commit() is called.
363 pending_origin_offset_ += config.origin_offset; 363 pending_origin_offset_ += config.origin_offset;
364 364
365 // Set the resize direction that will be applied when Commit() is called. 365 // Set the resize direction that will be applied when Commit() is called.
366 pending_resize_component_ = config.resize_component; 366 pending_resize_component_ = config.resize_component;
367 367
368 if (config.serial == serial) 368 if (config.serial == serial)
369 break; 369 break;
370 } 370 }
371 371
372 if (widget_) 372 if (widget_) {
373 UpdateWidgetBounds(); 373 UpdateWidgetBounds();
374 UpdateShadow();
375 }
374 } 376 }
375 377
376 void ShellSurface::SetParent(ShellSurface* parent) { 378 void ShellSurface::SetParent(ShellSurface* parent) {
377 TRACE_EVENT1("exo", "ShellSurface::SetParent", "parent", 379 TRACE_EVENT1("exo", "ShellSurface::SetParent", "parent",
378 parent ? base::UTF16ToASCII(parent->title_) : "null"); 380 parent ? base::UTF16ToASCII(parent->title_) : "null");
379 381
380 if (parent_) { 382 if (parent_) {
381 parent_->RemoveObserver(this); 383 parent_->RemoveObserver(this);
382 if (widget_) 384 if (widget_)
383 wm::RemoveTransientChild(parent_, widget_->GetNativeWindow()); 385 wm::RemoveTransientChild(parent_, widget_->GetNativeWindow());
(...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after
622 624
623 void ShellSurface::SetTopInset(int height) { 625 void ShellSurface::SetTopInset(int height) {
624 TRACE_EVENT1("exo", "ShellSurface::SetTopInset", "height", height); 626 TRACE_EVENT1("exo", "ShellSurface::SetTopInset", "height", height);
625 627
626 pending_top_inset_height_ = height; 628 pending_top_inset_height_ = height;
627 } 629 }
628 630
629 void ShellSurface::SetOrigin(const gfx::Point& origin) { 631 void ShellSurface::SetOrigin(const gfx::Point& origin) {
630 TRACE_EVENT1("exo", "ShellSurface::SetOrigin", "origin", origin.ToString()); 632 TRACE_EVENT1("exo", "ShellSurface::SetOrigin", "origin", origin.ToString());
631 633
634 const gfx::Point old_origin = origin_;
reveman 2017/02/18 00:32:39 nit: exo and chromium code typically doesn't use c
Dominik Laskowski 2017/02/23 03:43:48 Done.
632 origin_ = origin; 635 origin_ = origin;
636
637 if (bounds_mode_ != BoundsMode::CLIENT || origin == old_origin)
reveman 2017/02/18 00:32:39 nit: can you move the "origin == old_origin" check
Dominik Laskowski 2017/02/23 03:43:48 Done.
638 return;
639
640 // If the origin changed, give the client a chance to adjust window positions
641 // before switching to the new coordinate system. Retain the old origin by
642 // reverting the origin delta until the next configure is acknowledged.
643 const gfx::Vector2d delta = origin - old_origin;
644 origin_offset_ -= delta;
645 pending_origin_offset_accumulator_ += delta;
646
647 if (widget_) {
648 UpdateWidgetBounds();
649 UpdateShadow();
650 }
651
652 Configure();
633 } 653 }
634 654
635 void ShellSurface::SetActivatable(bool activatable) { 655 void ShellSurface::SetActivatable(bool activatable) {
636 TRACE_EVENT1("exo", "ShellSurface::SetActivatable", "activatable", 656 TRACE_EVENT1("exo", "ShellSurface::SetActivatable", "activatable",
637 activatable); 657 activatable);
638 658
639 activatable_ = activatable; 659 activatable_ = activatable;
640 } 660 }
641 661
642 void ShellSurface::SetContainer(int container) { 662 void ShellSurface::SetContainer(int container) {
(...skipping 26 matching lines...) Expand all
669 689
670 //////////////////////////////////////////////////////////////////////////////// 690 ////////////////////////////////////////////////////////////////////////////////
671 // SurfaceDelegate overrides: 691 // SurfaceDelegate overrides:
672 692
673 void ShellSurface::OnSurfaceCommit() { 693 void ShellSurface::OnSurfaceCommit() {
674 surface_->CheckIfSurfaceHierarchyNeedsCommitToNewSurfaces(); 694 surface_->CheckIfSurfaceHierarchyNeedsCommitToNewSurfaces();
675 surface_->CommitSurfaceHierarchy(); 695 surface_->CommitSurfaceHierarchy();
676 696
677 if (enabled() && !widget_) { 697 if (enabled() && !widget_) {
678 // Defer widget creation until surface contains some contents. 698 // Defer widget creation until surface contains some contents.
679 if (surface_->content_size().IsEmpty()) 699 if (surface_->content_size().IsEmpty()) {
680 Configure(); 700 Configure();
681 else 701 return;
682 CreateShellSurfaceWidget(ui::SHOW_STATE_NORMAL); 702 }
703
704 CreateShellSurfaceWidget(ui::SHOW_STATE_NORMAL);
683 } 705 }
684 706
685 // Apply the accumulated pending origin offset to reflect acknowledged 707 // Apply the accumulated pending origin offset to reflect acknowledged
686 // configure requests. 708 // configure requests.
687 origin_offset_ += pending_origin_offset_; 709 origin_offset_ += pending_origin_offset_;
688 pending_origin_offset_ = gfx::Vector2d(); 710 pending_origin_offset_ = gfx::Vector2d();
689 711
690 // Update resize direction to reflect acknowledged configure requests. 712 // Update resize direction to reflect acknowledged configure requests.
691 resize_component_ = pending_resize_component_; 713 resize_component_ = pending_resize_component_;
692 714
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after
864 ash::wm::WindowState* window_state, 886 ash::wm::WindowState* window_state,
865 ash::wm::WindowStateType old_type) { 887 ash::wm::WindowStateType old_type) {
866 ash::wm::WindowStateType new_type = window_state->GetStateType(); 888 ash::wm::WindowStateType new_type = window_state->GetStateType();
867 if (ash::wm::IsMaximizedOrFullscreenOrPinnedWindowStateType(old_type) || 889 if (ash::wm::IsMaximizedOrFullscreenOrPinnedWindowStateType(old_type) ||
868 ash::wm::IsMaximizedOrFullscreenOrPinnedWindowStateType(new_type)) { 890 ash::wm::IsMaximizedOrFullscreenOrPinnedWindowStateType(new_type)) {
869 // When transitioning in/out of maximized or fullscreen mode we need to 891 // When transitioning in/out of maximized or fullscreen mode we need to
870 // make sure we have a configure callback before we allow the default 892 // make sure we have a configure callback before we allow the default
871 // cross-fade animations. The configure callback provides a mechanism for 893 // cross-fade animations. The configure callback provides a mechanism for
872 // the client to inform us that a frame has taken the state change into 894 // the client to inform us that a frame has taken the state change into
873 // account and without this cross-fade animations are unreliable. 895 // account and without this cross-fade animations are unreliable.
874 if (configure_callback_.is_null()) 896
897 // TODO(domlaskowski): For shell surfaces whose bounds are controlled by the
898 // client, the configure callback does not yet support window state changes.
899 if (configure_callback_.is_null() || bounds_mode_ == BoundsMode::CLIENT)
875 scoped_animations_disabled_.reset(new ScopedAnimationsDisabled(this)); 900 scoped_animations_disabled_.reset(new ScopedAnimationsDisabled(this));
876 } 901 }
877 } 902 }
878 903
879 void ShellSurface::OnPostWindowStateTypeChange( 904 void ShellSurface::OnPostWindowStateTypeChange(
880 ash::wm::WindowState* window_state, 905 ash::wm::WindowState* window_state,
881 ash::wm::WindowStateType old_type) { 906 ash::wm::WindowStateType old_type) {
882 ash::wm::WindowStateType new_type = window_state->GetStateType(); 907 ash::wm::WindowStateType new_type = window_state->GetStateType();
883 if (ash::wm::IsMaximizedOrFullscreenOrPinnedWindowStateType(old_type) || 908 if (ash::wm::IsMaximizedOrFullscreenOrPinnedWindowStateType(old_type) ||
884 ash::wm::IsMaximizedOrFullscreenOrPinnedWindowStateType(new_type)) { 909 ash::wm::IsMaximizedOrFullscreenOrPinnedWindowStateType(new_type)) {
(...skipping 11 matching lines...) Expand all
896 // Re-enable animations if they were disabled in pre state change handler. 921 // Re-enable animations if they were disabled in pre state change handler.
897 scoped_animations_disabled_.reset(); 922 scoped_animations_disabled_.reset();
898 } 923 }
899 924
900 //////////////////////////////////////////////////////////////////////////////// 925 ////////////////////////////////////////////////////////////////////////////////
901 // aura::WindowObserver overrides: 926 // aura::WindowObserver overrides:
902 927
903 void ShellSurface::OnWindowBoundsChanged(aura::Window* window, 928 void ShellSurface::OnWindowBoundsChanged(aura::Window* window,
904 const gfx::Rect& old_bounds, 929 const gfx::Rect& old_bounds,
905 const gfx::Rect& new_bounds) { 930 const gfx::Rect& new_bounds) {
906 if (!widget_ || !surface_ || ignore_window_bounds_changes_) 931 if (bounds_mode_ == BoundsMode::CLIENT || !widget_ || !surface_ ||
reveman 2017/02/18 00:32:39 nit: is this needed as part of this patch? in that
Dominik Laskowski 2017/02/23 03:43:48 Yes, but it will be removed once resizing is drive
932 ignore_window_bounds_changes_)
907 return; 933 return;
908 934
909 if (window == widget_->GetNativeWindow()) { 935 if (window == widget_->GetNativeWindow()) {
910 if (new_bounds.size() == old_bounds.size()) 936 if (new_bounds.size() == old_bounds.size())
911 return; 937 return;
912 938
913 // If size changed then give the client a chance to produce new contents 939 // If size changed then give the client a chance to produce new contents
914 // before origin on screen is changed. Retain the old origin by reverting 940 // before origin on screen is changed. Retain the old origin by reverting
915 // the origin delta until the next configure is acknowledged. 941 // the origin delta until the next configure is acknowledged.
916 gfx::Vector2d delta = new_bounds.origin() - old_bounds.origin(); 942 gfx::Vector2d delta = new_bounds.origin() - old_bounds.origin();
(...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after
1147 resize_component = window_state->drag_details()->window_component; 1173 resize_component = window_state->drag_details()->window_component;
1148 } 1174 }
1149 1175
1150 uint32_t serial = 0; 1176 uint32_t serial = 0;
1151 if (!configure_callback_.is_null()) { 1177 if (!configure_callback_.is_null()) {
1152 if (widget_) { 1178 if (widget_) {
1153 const views::NonClientView* non_client_view = widget_->non_client_view(); 1179 const views::NonClientView* non_client_view = widget_->non_client_view();
1154 serial = configure_callback_.Run( 1180 serial = configure_callback_.Run(
1155 non_client_view->frame_view()->GetBoundsForClientView().size(), 1181 non_client_view->frame_view()->GetBoundsForClientView().size(),
1156 ash::wm::GetWindowState(widget_->GetNativeWindow())->GetStateType(), 1182 ash::wm::GetWindowState(widget_->GetNativeWindow())->GetStateType(),
1157 IsResizing(), widget_->IsActive()); 1183 IsResizing(), widget_->IsActive(), origin_);
1158 } else { 1184 } else {
1159 serial = configure_callback_.Run( 1185 serial = configure_callback_.Run(gfx::Size(),
1160 gfx::Size(), ash::wm::WINDOW_STATE_TYPE_NORMAL, false, false); 1186 ash::wm::WINDOW_STATE_TYPE_NORMAL, false,
1187 false, origin_);
1161 } 1188 }
1162 } 1189 }
1163 1190
1164 if (!serial) { 1191 if (!serial) {
1165 pending_origin_offset_ += origin_offset; 1192 pending_origin_offset_ += origin_offset;
1166 pending_resize_component_ = resize_component; 1193 pending_resize_component_ = resize_component;
1167 return; 1194 return;
1168 } 1195 }
1169 1196
1170 // Apply origin offset and resize component at the first Commit() after this 1197 // Apply origin offset and resize component at the first Commit() after this
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
1286 gfx::Rect ShellSurface::GetVisibleBounds() const { 1313 gfx::Rect ShellSurface::GetVisibleBounds() const {
1287 // Use |geometry_| if set, otherwise use the visual bounds of the surface. 1314 // Use |geometry_| if set, otherwise use the visual bounds of the surface.
1288 return geometry_.IsEmpty() ? gfx::Rect(surface_->window()->layer()->size()) 1315 return geometry_.IsEmpty() ? gfx::Rect(surface_->window()->layer()->size())
1289 : geometry_; 1316 : geometry_;
1290 } 1317 }
1291 1318
1292 gfx::Point ShellSurface::GetSurfaceOrigin() const { 1319 gfx::Point ShellSurface::GetSurfaceOrigin() const {
1293 // For client-positioned shell surfaces, the surface origin corresponds to the 1320 // For client-positioned shell surfaces, the surface origin corresponds to the
1294 // widget position relative to the origin specified by the client. Since the 1321 // widget position relative to the origin specified by the client. Since the
1295 // surface is positioned relative to the widget, negate this vector to align 1322 // surface is positioned relative to the widget, negate this vector to align
1296 // the surface with the widget. 1323 // the surface with the widget. Note that the widget position must have been
reveman 2017/02/18 00:32:39 hm, I'd expect CLIENT bounds to behave just like S
Dominik Laskowski 2017/02/23 03:43:48 I've removed the special case below to avoid depen
1324 // adjusted by the |origin_offset_| prior to this call.
1297 if (bounds_mode_ != BoundsMode::SHELL) { 1325 if (bounds_mode_ != BoundsMode::SHELL) {
1298 gfx::Point position = widget_->GetNativeWindow()->bounds().origin(); 1326 gfx::Point position = widget_->GetNativeWindow()->bounds().origin();
1299 wm::ConvertPointToScreen(widget_->GetNativeWindow()->parent(), &position); 1327 wm::ConvertPointToScreen(widget_->GetNativeWindow()->parent(), &position);
1300 return origin_ - position.OffsetFromOrigin(); 1328 return origin_ - position.OffsetFromOrigin();
1301 } 1329 }
1302 1330
1303 gfx::Rect visible_bounds = GetVisibleBounds(); 1331 gfx::Rect visible_bounds = GetVisibleBounds();
1304 gfx::Rect client_bounds = 1332 gfx::Rect client_bounds =
1305 widget_->non_client_view()->frame_view()->GetBoundsForClientView(); 1333 widget_->non_client_view()->frame_view()->GetBoundsForClientView();
1306 switch (resize_component_) { 1334 switch (resize_component_) {
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
1349 if (!pending_configs_.empty() || scoped_configure_) 1377 if (!pending_configs_.empty() || scoped_configure_)
1350 return; 1378 return;
1351 1379
1352 gfx::Rect visible_bounds = GetVisibleBounds(); 1380 gfx::Rect visible_bounds = GetVisibleBounds();
1353 gfx::Rect new_widget_bounds = 1381 gfx::Rect new_widget_bounds =
1354 widget_->non_client_view()->GetWindowBoundsForClientBounds( 1382 widget_->non_client_view()->GetWindowBoundsForClientBounds(
1355 visible_bounds); 1383 visible_bounds);
1356 1384
1357 switch (bounds_mode_) { 1385 switch (bounds_mode_) {
1358 case BoundsMode::CLIENT: 1386 case BoundsMode::CLIENT:
1387 // Position is relative to the latest origin acknowledged by the client.
reveman 2017/02/18 00:32:39 Can we have this behave as the SHELL when "resize_
Dominik Laskowski 2017/02/23 03:43:48 I've simplified this a bit, but I don't think unif
1388 new_widget_bounds -= origin_offset_;
1389 break;
1359 case BoundsMode::FIXED: 1390 case BoundsMode::FIXED:
1360 // Position is relative to the origin. 1391 // Position is relative to the origin.
1361 new_widget_bounds += origin_.OffsetFromOrigin(); 1392 new_widget_bounds += origin_.OffsetFromOrigin();
1362 break; 1393 break;
1363 case BoundsMode::SHELL: 1394 case BoundsMode::SHELL:
1364 // Update widget origin using the surface origin if the current location 1395 // Update widget origin using the surface origin if the current location
1365 // of surface is being anchored to one side of the widget as a result of a 1396 // of surface is being anchored to one side of the widget as a result of a
1366 // resize operation. 1397 // resize operation.
1367 if (resize_component_ != HTCAPTION) { 1398 if (resize_component_ != HTCAPTION) {
1368 gfx::Point widget_origin = 1399 gfx::Point widget_origin =
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
1411 if (shadow_underlay_bounds.IsEmpty()) 1442 if (shadow_underlay_bounds.IsEmpty())
1412 shadow_underlay_bounds = gfx::Rect(surface_->window()->bounds().size()); 1443 shadow_underlay_bounds = gfx::Rect(surface_->window()->bounds().size());
1413 1444
1414 if (!shadow_underlay_in_surface_) { 1445 if (!shadow_underlay_in_surface_) {
1415 shadow_content_bounds = shadow_content_bounds_; 1446 shadow_content_bounds = shadow_content_bounds_;
1416 if (shadow_content_bounds.IsEmpty()) { 1447 if (shadow_content_bounds.IsEmpty()) {
1417 shadow_content_bounds = window->bounds(); 1448 shadow_content_bounds = window->bounds();
1418 } 1449 }
1419 } 1450 }
1420 1451
1421 // TODO(oshima): Adjust the coordinates from client screen to 1452 gfx::Point shadow_origin = shadow_content_bounds.origin() - origin_offset_;
1422 // chromeos screen when multi displays are supported. 1453 wm::ConvertPointFromScreen(window->parent(), &shadow_origin);
1423 gfx::Point origin = window->bounds().origin(); 1454 shadow_origin -= window->bounds().OffsetFromOrigin();
1424 gfx::Point shadow_origin = shadow_content_bounds.origin();
1425 shadow_origin -= origin.OffsetFromOrigin();
1426 gfx::Rect shadow_bounds(shadow_origin, shadow_content_bounds.size()); 1455 gfx::Rect shadow_bounds(shadow_origin, shadow_content_bounds.size());
1427 1456
1428 // Always create and show the underlay, even in maximized/fullscreen. 1457 // Always create and show the underlay, even in maximized/fullscreen.
1429 if (!shadow_underlay_) { 1458 if (!shadow_underlay_) {
1430 shadow_underlay_ = new aura::Window(nullptr); 1459 shadow_underlay_ = new aura::Window(nullptr);
1431 shadow_underlay_event_handler_ = 1460 shadow_underlay_event_handler_ =
1432 base::MakeUnique<ShadowUnderlayEventHandler>(); 1461 base::MakeUnique<ShadowUnderlayEventHandler>();
1433 shadow_underlay_->SetTargetHandler(shadow_underlay_event_handler_.get()); 1462 shadow_underlay_->SetTargetHandler(shadow_underlay_event_handler_.get());
1434 DCHECK(shadow_underlay_->owned_by_parent()); 1463 DCHECK(shadow_underlay_->owned_by_parent());
1435 // Ensure the background area inside the shadow is solid black. 1464 // Ensure the background area inside the shadow is solid black.
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
1521 // small style shadow for them. 1550 // small style shadow for them.
1522 if (!activatable_) 1551 if (!activatable_)
1523 shadow->SetElevation(wm::ShadowElevation::SMALL); 1552 shadow->SetElevation(wm::ShadowElevation::SMALL);
1524 // We don't have rounded corners unless frame is enabled. 1553 // We don't have rounded corners unless frame is enabled.
1525 if (!frame_enabled_) 1554 if (!frame_enabled_)
1526 shadow->SetRoundedCornerRadius(0); 1555 shadow->SetRoundedCornerRadius(0);
1527 } 1556 }
1528 } 1557 }
1529 1558
1530 } // namespace exo 1559 } // namespace exo
OLDNEW
« no previous file with comments | « components/exo/shell_surface.h ('k') | components/exo/shell_surface_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698