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

Unified Diff: components/exo/shell_surface.cc

Issue 2688483003: exo: Refactor ShellSurface and WaylandRemoteShell (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 side-by-side diff with in-line comments
Download patch
Index: components/exo/shell_surface.cc
diff --git a/components/exo/shell_surface.cc b/components/exo/shell_surface.cc
index a0c2a59d8fcb75c9960f355202e5abda625af83d..ba845251eb0fe7864cf065cdb58d884e941fba2a 100644
--- a/components/exo/shell_surface.cc
+++ b/components/exo/shell_surface.cc
@@ -335,14 +335,16 @@ DEFINE_LOCAL_UI_CLASS_PROPERTY_KEY(Surface*, kMainSurfaceKey, nullptr)
ShellSurface::ShellSurface(Surface* surface,
ShellSurface* parent,
- const gfx::Rect& initial_bounds,
+ BoundsMode bounds_mode,
+ const gfx::Point& origin,
bool activatable,
bool can_minimize,
int container)
: widget_(nullptr),
surface_(surface),
parent_(parent ? parent->GetWidget()->GetNativeWindow() : nullptr),
- initial_bounds_(initial_bounds),
+ bounds_mode_(bounds_mode),
+ origin_(origin),
activatable_(activatable),
can_minimize_(can_minimize),
container_(container) {
@@ -358,7 +360,8 @@ ShellSurface::ShellSurface(Surface* surface,
ShellSurface::ShellSurface(Surface* surface)
: ShellSurface(surface,
nullptr,
- gfx::Rect(),
+ BoundsMode::SHELL,
+ gfx::Point(),
true,
true,
ash::kShellWindowId_DefaultContainer) {}
@@ -564,15 +567,35 @@ void ShellSurface::SetApplicationId(const std::string& application_id) {
void ShellSurface::Move() {
TRACE_EVENT0("exo", "ShellSurface::Move");
- if (widget_ && !widget_->movement_disabled())
- AttemptToStartDrag(HTCAPTION);
+ if (!widget_)
+ return;
+
+ switch (bounds_mode_) {
+ case BoundsMode::SHELL:
+ AttemptToStartDrag(HTCAPTION);
+ break;
+ case BoundsMode::CLIENT:
+ case BoundsMode::FIXED:
+ NOTREACHED();
reveman 2017/02/09 04:50:15 How are we protected from a malicious client causi
Dominik Laskowski 2017/02/09 23:35:28 NOTREACHED only logs an error in release builds.
reveman 2017/02/10 02:10:53 A malicious client being able to crash a debug bui
+ break;
+ }
reveman 2017/02/09 04:50:16 nit: please add return statements in the switch ca
Dominik Laskowski 2017/02/09 23:35:28 Done.
}
void ShellSurface::Resize(int component) {
TRACE_EVENT1("exo", "ShellSurface::Resize", "component", component);
- if (widget_ && !widget_->movement_disabled())
- AttemptToStartDrag(component);
+ if (!widget_)
+ return;
+
+ switch (bounds_mode_) {
reveman 2017/02/09 04:50:15 same comments here
Dominik Laskowski 2017/02/09 23:35:28 Done.
+ case BoundsMode::SHELL:
+ AttemptToStartDrag(component);
+ break;
+ case BoundsMode::CLIENT:
+ case BoundsMode::FIXED:
+ NOTREACHED();
+ break;
+ }
}
void ShellSurface::Close() {
@@ -649,7 +672,7 @@ void ShellSurface::SetTopInset(int height) {
void ShellSurface::SetOrigin(const gfx::Point& origin) {
TRACE_EVENT1("exo", "ShellSurface::SetOrigin", "origin", origin.ToString());
- initial_bounds_ = gfx::Rect(origin, gfx::Size(1, 1));
+ origin_ = origin;
}
void ShellSurface::SetActivatable(bool activatable) {
@@ -704,7 +727,7 @@ void ShellSurface::OnSurfaceCommit() {
// Apply the accumulated pending origin offset to reflect acknowledged
// configure requests.
- origin_ += pending_origin_offset_;
+ origin_offset_ += pending_origin_offset_;
pending_origin_offset_ = gfx::Vector2d();
// Update resize direction to reflect acknowledged configure requests.
@@ -743,13 +766,7 @@ void ShellSurface::OnSurfaceCommit() {
}
}
- gfx::Rect client_view_bounds =
- widget_->non_client_view()->frame_view()->GetBoundsForClientView();
-
- // Update surface bounds.
- surface_->window()->SetBounds(
- gfx::Rect(GetSurfaceOrigin() + client_view_bounds.OffsetFromOrigin(),
- surface_->window()->layer()->size()));
+ UpdateSurfaceBounds();
// Update surface scale.
if (pending_scale_ != scale_) {
@@ -806,7 +823,7 @@ void ShellSurface::OnSurfaceDestroying(Surface* surface) {
// views::WidgetDelegate overrides:
bool ShellSurface::CanResize() const {
- return initial_bounds_.IsEmpty();
+ return bounds_mode_ == BoundsMode::SHELL;
}
bool ShellSurface::CanMaximize() const {
@@ -940,19 +957,13 @@ void ShellSurface::OnWindowBoundsChanged(aura::Window* window,
return;
// If size changed then give the client a chance to produce new contents
- // before origin on screen is changed by adding offset to the next configure
- // request and offset |origin_| by the same distance.
- gfx::Vector2d origin_offset = new_bounds.origin() - old_bounds.origin();
- pending_origin_config_offset_ += origin_offset;
- origin_ -= origin_offset;
-
- gfx::Rect client_view_bounds =
- widget_->non_client_view()->frame_view()->GetBoundsForClientView();
+ // before origin on screen is changed. Retain the old origin by reverting
+ // the origin delta until the next configure is acknowledged.
+ const gfx::Vector2d delta = new_bounds.origin() - old_bounds.origin();
+ origin_offset_ -= delta;
+ pending_origin_offset_accumulator_ += delta;
- // Update surface bounds.
- surface_->window()->SetBounds(
- gfx::Rect(GetSurfaceOrigin() + client_view_bounds.OffsetFromOrigin(),
- surface_->window()->layer()->size()));
+ UpdateSurfaceBounds();
// The shadow size may be updated to match the widget. Change it back
// to the shadow content size.
@@ -1094,7 +1105,7 @@ void ShellSurface::CreateShellSurfaceWidget(ui::WindowShowState show_state) {
// Make shell surface a transient child if |parent_| has been set.
params.parent =
parent_ ? parent_ : WMHelper::GetInstance()->GetContainer(container_);
- params.bounds = initial_bounds_;
+ params.bounds = gfx::Rect(origin_, gfx::Size());
bool activatable = activatable_;
// ShellSurfaces in system modal container are only activatable if input
// region is non-empty. See OnCommitSurface() for more details.
@@ -1116,16 +1127,17 @@ void ShellSurface::CreateShellSurfaceWidget(ui::WindowShowState show_state) {
SetApplicationId(window, application_id_);
SetMainSurface(window, surface_);
+ const bool client_controls_bounds = bounds_mode_ == BoundsMode::CLIENT;
reveman 2017/02/09 04:50:15 nit: remove 'const'. doesn't hurt but typically no
Dominik Laskowski 2017/02/09 23:35:28 Removed variable along with check below.
+
// Start tracking changes to window bounds and window state.
- window->AddObserver(this);
+ if (!client_controls_bounds)
reveman 2017/02/09 04:50:15 can we add the observer unconditionally and instea
Dominik Laskowski 2017/02/09 23:35:28 Done.
+ window->AddObserver(this);
ash::wm::WindowState* window_state = ash::wm::GetWindowState(window);
window_state->AddObserver(this);
- // Absolete positioned shell surfaces may request the bounds that does not
- // fill the entire work area / display in maximized / fullscreen state.
- // Allow such clients to update the bounds in these states.
- if (!initial_bounds_.IsEmpty())
- window_state->set_allow_set_bounds_in_maximized(true);
+ // Allow the client to request bounds that do not fill the entire work area
+ // when maximized, or the entire display when fullscreen.
+ window_state->set_allow_set_bounds_in_maximized(client_controls_bounds);
// Notify client of initial state if different than normal.
if (window_state->GetStateType() != ash::wm::WINDOW_STATE_TYPE_NORMAL &&
@@ -1134,9 +1146,10 @@ void ShellSurface::CreateShellSurfaceWidget(ui::WindowShowState show_state) {
window_state->GetStateType());
}
- // Disable movement if initial bounds were specified.
- widget_->set_movement_disabled(!initial_bounds_.IsEmpty());
- window_state->set_ignore_keyboard_bounds_change(!initial_bounds_.IsEmpty());
+ // Disable movement if bounds are controlled by the client or fixed.
+ const bool movement_disabled = bounds_mode_ != BoundsMode::SHELL;
reveman 2017/02/09 04:50:15 nit: remove 'const'
Dominik Laskowski 2017/02/09 23:35:28 Done.
+ widget_->set_movement_disabled(movement_disabled);
+ window_state->set_ignore_keyboard_bounds_change(movement_disabled);
// AutoHide shelf in fullscreen state.
window_state->set_hide_shelf_when_fullscreen(false);
@@ -1169,8 +1182,8 @@ void ShellSurface::Configure() {
return;
}
- gfx::Vector2d origin_offset = pending_origin_config_offset_;
- pending_origin_config_offset_ = gfx::Vector2d();
+ const gfx::Vector2d origin_offset = pending_origin_offset_accumulator_;
reveman 2017/02/09 04:50:15 nit: remove 'const'
Dominik Laskowski 2017/02/09 23:35:28 Done.
+ pending_origin_offset_accumulator_ = gfx::Vector2d();
int resize_component = HTCAPTION;
if (widget_) {
@@ -1274,7 +1287,7 @@ void ShellSurface::AttemptToStartDrag(int component) {
// Apply pending origin offsets and resize direction before starting a new
// resize operation. These can still be pending if the client has acknowledged
// the configure request but not yet called Commit().
- origin_ += pending_origin_offset_;
+ origin_offset_ += pending_origin_offset_;
pending_origin_offset_ = gfx::Vector2d();
resize_component_ = pending_resize_component_;
@@ -1290,22 +1303,31 @@ void ShellSurface::EndDrag(bool revert) {
DCHECK(widget_);
DCHECK(resizer_);
- bool was_resizing = IsResizing();
+ switch (bounds_mode_) {
+ case BoundsMode::SHELL: {
+ bool was_resizing = IsResizing();
- if (revert)
- resizer_->RevertDrag();
- else
- resizer_->CompleteDrag();
+ if (revert)
+ resizer_->RevertDrag();
+ else
+ resizer_->CompleteDrag();
- WMHelper::GetInstance()->RemovePreTargetHandler(this);
- widget_->GetNativeWindow()->ReleaseCapture();
- resizer_.reset();
+ WMHelper::GetInstance()->RemovePreTargetHandler(this);
+ widget_->GetNativeWindow()->ReleaseCapture();
+ resizer_.reset();
- // Notify client that resizing state has changed.
- if (was_resizing)
- Configure();
+ // Notify client that resizing state has changed.
+ if (was_resizing)
+ Configure();
- UpdateWidgetBounds();
+ UpdateWidgetBounds();
+ break;
+ }
+ case BoundsMode::CLIENT:
+ case BoundsMode::FIXED:
+ NOTREACHED();
reveman 2017/02/09 04:50:15 Can a malicious client cause this?
Dominik Laskowski 2017/02/09 23:35:28 Only debug builds would crash.
reveman 2017/02/10 02:10:53 Debug builds crashing is not ok.
+ break;
+ }
reveman 2017/02/09 04:50:15 return above and NOTREACHED() here?
Dominik Laskowski 2017/02/09 23:35:28 Done.
}
bool ShellSurface::IsResizing() const {
@@ -1325,12 +1347,14 @@ gfx::Rect ShellSurface::GetVisibleBounds() const {
}
gfx::Point ShellSurface::GetSurfaceOrigin() const {
- // If initial bounds were specified then surface origin is always relative
- // to those bounds.
- if (!initial_bounds_.IsEmpty()) {
- gfx::Point origin = widget_->GetNativeWindow()->bounds().origin();
- wm::ConvertPointToScreen(widget_->GetNativeWindow()->parent(), &origin);
- return initial_bounds_.origin() - origin.OffsetFromOrigin();
+ // For client-positioned shell surfaces, the surface origin corresponds to the
+ // widget position relative to the origin specified by the client. Since the
+ // surface is positioned relative to the widget, negate this vector to align
+ // the surface with the widget.
+ if (bounds_mode_ != BoundsMode::SHELL) {
+ gfx::Point position = widget_->GetNativeWindow()->bounds().origin();
+ wm::ConvertPointToScreen(widget_->GetNativeWindow()->parent(), &position);
+ return origin_ - position.OffsetFromOrigin();
}
gfx::Rect visible_bounds = GetVisibleBounds();
@@ -1338,7 +1362,7 @@ gfx::Point ShellSurface::GetSurfaceOrigin() const {
widget_->non_client_view()->frame_view()->GetBoundsForClientView();
switch (resize_component_) {
case HTCAPTION:
- return origin_ - visible_bounds.OffsetFromOrigin();
+ return gfx::Point() + origin_offset_ - visible_bounds.OffsetFromOrigin();
case HTBOTTOM:
case HTRIGHT:
case HTBOTTOMRIGHT:
@@ -1347,7 +1371,6 @@ gfx::Point ShellSurface::GetSurfaceOrigin() const {
case HTTOPRIGHT:
return gfx::Point(0, client_bounds.height() - visible_bounds.height()) -
visible_bounds.OffsetFromOrigin();
- break;
case HTLEFT:
case HTBOTTOMLEFT:
return gfx::Point(client_bounds.width() - visible_bounds.width(), 0) -
@@ -1366,18 +1389,17 @@ void ShellSurface::UpdateWidgetBounds() {
DCHECK(widget_);
// Return early if the shell is currently managing the bounds of the widget.
- // 1) When a window is either maximized/fullscreen/pinned, and the bounds
- // isn't controlled by a client.
- ash::wm::WindowState* window_state =
- ash::wm::GetWindowState(widget_->GetNativeWindow());
- if (window_state->IsMaximizedOrFullscreenOrPinned() &&
- !window_state->allow_set_bounds_in_maximized()) {
- return;
- }
+ if (bounds_mode_ == BoundsMode::SHELL) {
+ // 1) When a window is either maximized/fullscreen/pinned.
+ ash::wm::WindowState* window_state =
+ ash::wm::GetWindowState(widget_->GetNativeWindow());
+ if (window_state->IsMaximizedOrFullscreenOrPinned())
+ return;
- // 2) When a window is being dragged.
- if (IsResizing())
- return;
+ // 2) When a window is being dragged.
+ if (IsResizing())
+ return;
+ }
// Return early if there is pending configure requests.
if (!pending_configs_.empty() || scoped_configure_)
@@ -1388,23 +1410,27 @@ void ShellSurface::UpdateWidgetBounds() {
widget_->non_client_view()->GetWindowBoundsForClientBounds(
visible_bounds);
- // Avoid changing widget origin unless initial bounds were specified and
- // widget origin is always relative to it.
- if (initial_bounds_.IsEmpty()) {
- new_widget_bounds.set_origin(widget_->GetWindowBoundsInScreen().origin());
- } else {
- new_widget_bounds.set_origin(initial_bounds_.origin() +
- visible_bounds.OffsetFromOrigin());
- }
-
- // Update widget origin using the surface origin if the current location of
- // surface is being anchored to one side of the widget as a result of a
- // resize operation.
- if (resize_component_ != HTCAPTION) {
- gfx::Point new_widget_origin =
- GetSurfaceOrigin() + visible_bounds.OffsetFromOrigin();
- wm::ConvertPointToScreen(widget_->GetNativeWindow(), &new_widget_origin);
- new_widget_bounds.set_origin(new_widget_origin);
+ switch (bounds_mode_) {
+ case BoundsMode::CLIENT:
+ case BoundsMode::FIXED:
+ // Position is relative to the origin.
+ new_widget_bounds += origin_.OffsetFromOrigin();
+ break;
+ case BoundsMode::SHELL:
+ // Update widget origin using the surface origin if the current location
+ // of surface is being anchored to one side of the widget as a result of a
+ // resize operation.
+ if (resize_component_ != HTCAPTION) {
+ gfx::Point widget_origin =
+ GetSurfaceOrigin() + visible_bounds.OffsetFromOrigin();
+ wm::ConvertPointToScreen(widget_->GetNativeWindow(), &widget_origin);
+ new_widget_bounds.set_origin(widget_origin);
+ } else {
+ // Preserve widget position.
+ new_widget_bounds.set_origin(
+ widget_->GetWindowBoundsInScreen().origin());
+ }
+ break;
}
// Set |ignore_window_bounds_changes_| as this change to window bounds
@@ -1414,11 +1440,12 @@ void ShellSurface::UpdateWidgetBounds() {
if (widget_->GetWindowBoundsInScreen() != new_widget_bounds)
widget_->SetBounds(new_widget_bounds);
ignore_window_bounds_changes_ = false;
+}
- gfx::Rect client_view_bounds =
+void ShellSurface::UpdateSurfaceBounds() {
+ const gfx::Rect client_view_bounds =
widget_->non_client_view()->frame_view()->GetBoundsForClientView();
- // A change to the widget size requires surface bounds to be re-adjusted.
surface_->window()->SetBounds(
gfx::Rect(GetSurfaceOrigin() + client_view_bounds.OffsetFromOrigin(),
surface_->window()->layer()->size()));

Powered by Google App Engine
This is Rietveld 408576698