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

Unified Diff: ui/views/cocoa/bridged_native_widget.mm

Issue 831643004: MacViews: Fix child window z-order and SetBounds (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: CHECK->EXPECT_TRUE Created 5 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | ui/views/test/widget_test.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: ui/views/cocoa/bridged_native_widget.mm
diff --git a/ui/views/cocoa/bridged_native_widget.mm b/ui/views/cocoa/bridged_native_widget.mm
index ed1339d38afd318d0bf43b44f67c94dfdcabc8fb..0ff084572f70ddc519f5ded156a87c30fd1ecbf4 100644
--- a/ui/views/cocoa/bridged_native_widget.mm
+++ b/ui/views/cocoa/bridged_native_widget.mm
@@ -125,7 +125,11 @@ void BridgedNativeWidget::SetFocusManager(FocusManager* focus_manager) {
}
void BridgedNativeWidget::SetBounds(const gfx::Rect& new_bounds) {
- [window_ setFrame:gfx::ScreenRectToNSRect(new_bounds)
+ gfx::Rect actual_new_bounds(new_bounds);
+ if (parent_)
+ actual_new_bounds.Offset(parent_->GetRestoredBounds().OffsetFromOrigin());
+
+ [window_ setFrame:gfx::ScreenRectToNSRect(actual_new_bounds)
display:YES
animate:NO];
}
@@ -164,7 +168,6 @@ void BridgedNativeWidget::SetVisibilityState(WindowVisibilityState new_state) {
if (new_state == HIDE_WINDOW) {
[window_ orderOut:nil];
DCHECK(!window_visible_);
- NotifyVisibilityChangeDown();
return;
}
@@ -193,7 +196,6 @@ void BridgedNativeWidget::SetVisibilityState(WindowVisibilityState new_state) {
relativeTo:parent_window_number];
}
DCHECK(window_visible_);
- NotifyVisibilityChangeDown();
}
void BridgedNativeWidget::AcquireCapture() {
@@ -328,12 +330,20 @@ void BridgedNativeWidget::OnVisibilityChangedTo(bool new_visibility) {
// If made visible externally (e.g. Cmd+H), just roll with it. Don't try (yet)
// to distinguish being *hidden* externally from being hidden by a parent
// window - we might not need that.
- if (window_visible_)
+ if (window_visible_) {
wants_to_be_visible_ = true;
- // Capture on hidden windows is not permitted.
- if (!window_visible_)
- mouse_capture_.reset();
+ if (parent_)
+ [parent_->ns_window() addChildWindow:window_ ordered:NSWindowAbove];
+ } else {
+ mouse_capture_.reset(); // Capture on hidden windows is not permitted.
+
+ // When becoming invisible, remove the entry in any parent's childWindow
+ // list. Cocoa's childWindow management breaks down when child windows are
+ // hidden.
+ if (parent_)
+ [parent_->ns_window() removeChildWindow:window_];
+ }
// TODO(tapted): Investigate whether we want this for Mac. This is what Aura
// does, and it is what tests expect. However, because layer drawing is
@@ -347,6 +357,8 @@ void BridgedNativeWidget::OnVisibilityChangedTo(bool new_visibility) {
layer()->SchedulePaint(gfx::Rect(GetClientAreaSize()));
}
+ NotifyVisibilityChangeDown();
+
native_widget_mac_->GetWidget()->OnNativeWidgetVisibilityChanged(
window_visible_);
@@ -520,27 +532,43 @@ void BridgedNativeWidget::NotifyVisibilityChangeDown() {
const size_t child_count = child_windows_.size();
if (!window_visible_) {
for (BridgedNativeWidget* child : child_windows_) {
- if (child->window_visible_) {
+ if (child->window_visible_)
[child->ns_window() orderOut:nil];
- child->NotifyVisibilityChangeDown();
- CHECK_EQ(child_count, child_windows_.size());
- }
+
+ DCHECK(!child->window_visible_);
+ CHECK_EQ(child_count, child_windows_.size());
}
+ // The orderOut calls above should result in a call to OnVisibilityChanged()
+ // in each child. There, children will remove themselves from the NSWindow
+ // childWindow list as well as propagate NotifyVisibilityChangeDown() calls
+ // to any children of their own.
+ DCHECK_EQ(0u, [[window_ childWindows] count]);
return;
}
+ NSUInteger visible_children = 0; // For a DCHECK below.
NSInteger parent_window_number = [window_ windowNumber];
for (BridgedNativeWidget* child: child_windows_) {
// Note: order the child windows on top, regardless of whether or not they
// are currently visible. They probably aren't, since the parent was hidden
// prior to this, but they could have been made visible in other ways.
if (child->wants_to_be_visible_) {
+ ++visible_children;
+ // Here -[NSWindow orderWindow:relativeTo:] is used to put the window on
+ // screen. However, that by itself is insufficient to guarantee a correct
+ // z-order relationship. If this function is being called from a z-order
+ // change in the parent, orderWindow turns out to be unreliable (i.e. the
+ // ordering doesn't always take effect). What this actually relies on is
+ // the resulting call to OnVisibilityChanged() in the child, which will
+ // then insert itself into -[NSWindow childWindows] to let Cocoa do its
+ // internal layering magic.
[child->ns_window() orderWindow:NSWindowAbove
relativeTo:parent_window_number];
- child->NotifyVisibilityChangeDown();
- CHECK_EQ(child_count, child_windows_.size());
+ DCHECK(child->window_visible_);
}
+ CHECK_EQ(child_count, child_windows_.size());
}
+ DCHECK_EQ(visible_children, [[window_ childWindows] count]);
}
gfx::Size BridgedNativeWidget::GetClientAreaSize() const {
« no previous file with comments | « no previous file | ui/views/test/widget_test.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698