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

Unified Diff: ui/views/widget/widget_mac_utils.mm

Issue 1796773003: Implement NativeWidgetMac::ReorderNativeViews (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Implement NativeWidgetMac::ReorderNativeViews Created 4 years, 9 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 | « ui/views/widget/widget_mac_utils.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: ui/views/widget/widget_mac_utils.mm
diff --git a/ui/views/widget/widget_mac_utils.mm b/ui/views/widget/widget_mac_utils.mm
new file mode 100644
index 0000000000000000000000000000000000000000..a6126d889244277870ec10caccf00e098411094d
--- /dev/null
+++ b/ui/views/widget/widget_mac_utils.mm
@@ -0,0 +1,128 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ui/views/widget/widget_mac_utils.h"
+
+#import <objc/runtime.h>
+
+#include <vector>
+
+#include "base/mac/foundation_util.h"
+#include "ui/views/cocoa/bridged_content_view.h"
+#include "ui/views/controls/native/native_view_host.h"
+#include "ui/views/widget/widget.h"
+
+namespace views {
+namespace {
+
+using HostedViews = std::vector<std::pair<const views::View*, NSView*>>;
+
+struct EqualToView {
+ EqualToView(const views::View* view) : view_(view) {}
+ bool operator()(const HostedViews::value_type& v) const {
+ return v.first == view_;
+ }
+
+ private:
+ const views::View* view_;
+};
+
+struct EqualToNSView {
+ EqualToNSView(NSView* native_view) : native_view_(native_view) {}
+ bool operator()(const HostedViews::value_type& v) const {
+ return v.second == native_view_;
+ }
+
+ private:
+ NSView* native_view_;
+};
+
+HostedViews GetViewsWithAssociatedNativeViews(const Widget* widget) {
+ HostedViews result;
+ const auto* subviews = [widget->GetNativeView() subviews];
+ for (NSView* child in subviews) {
+ NSValue* value = objc_getAssociatedObject(child, &kAssociatedViewHostKey);
+ if (value)
+ result.emplace_back(static_cast<const views::View*>(value.pointerValue),
+ child);
+ }
+ return result;
+}
+
+HostedViews::iterator SortViewsList(const views::View* view,
+ HostedViews::iterator begin,
+ HostedViews::iterator end) {
+ auto it = std::find_if(begin, end, EqualToView(view));
+ if (it != end) {
+ std::swap(*begin, *it);
+ ++begin;
+ }
+ for (int i = 0; i < view->child_count(); ++i)
+ begin = SortViewsList(view->child_at(i), begin, end);
+ return begin;
+}
+
+NSComparisonResult SubviewSorter(id lhs, id rhs, void* hosts_as_void) {
+ DCHECK_NE(lhs, rhs);
+
+ const HostedViews* hosts = static_cast<const HostedViews*>(hosts_as_void);
+ auto left_it = std::find_if(hosts->begin(), hosts->end(), EqualToNSView(lhs));
tapted 2016/03/15 22:54:53 This call is O(n) so it makes the sorting algorith
kirr 2016/03/16 09:16:34 I used vector of pairs as one container for all (a
kirr 2016/03/16 21:43:45 Done.
+ auto right_it =
+ std::find_if(hosts->begin(), hosts->end(), EqualToNSView(rhs));
+ bool left_found = left_it != hosts->end();
+ bool right_found = right_it != hosts->end();
+
+ // Sort unassociated views below associated views.
+ if (left_found != right_found) {
tapted 2016/03/15 22:54:53 nit: doesn't need curlies
kirr 2016/03/16 21:43:45 Done.
+ return left_found ? NSOrderedDescending : NSOrderedAscending;
+ }
+
+ if (left_found)
tapted 2016/03/15 22:54:53 nit: needs curlies
kirr 2016/03/16 21:43:45 Done.
+ return std::distance(hosts->begin(), left_it) <
+ std::distance(hosts->begin(), right_it)
+ ? NSOrderedAscending
+ : NSOrderedDescending;
+
+ // If both are unassociated, consider that order is not important
+ return NSOrderedSame;
+}
+
+} // namespace
+
+int kAssociatedViewHostKey;
+
+void AttachNSViewRelatedToHost(NSView* native_view, NativeViewHost* host) {
tapted 2016/03/15 22:54:53 I don't think this function is necessary. Aura ob
kirr 2016/03/16 21:43:45 Done.
+ Widget* new_parent = host->GetWidget();
+ HostedViews hosts = GetViewsWithAssociatedNativeViews(new_parent);
+ hosts.emplace_back(host, native_view);
+ SortViewsList(new_parent->GetRootView(), hosts.begin(), hosts.end());
+
+ BridgedContentView* new_superview =
+ base::mac::ObjCCastStrict<BridgedContentView>(
+ new_parent->GetNativeView());
+ DCHECK(new_superview);
+
+ auto it = std::find_if(hosts.begin(), hosts.end(), EqualToView(host));
+ if (it == hosts.end() || (it + 1) == hosts.end()) {
+ [new_superview addSubview:native_view];
+ } else {
+ NSView* view_above = (it + 1)->second;
+ [new_superview addSubview:native_view
+ positioned:NSWindowBelow
+ relativeTo:view_above];
+ }
+}
+
+void ReorderChildNSViews(Widget* widget) {
+ HostedViews hosts = GetViewsWithAssociatedNativeViews(widget);
+ HostedViews sorted_hosts = hosts;
+ SortViewsList(widget->GetRootView(), sorted_hosts.begin(),
+ sorted_hosts.end());
+
+ if (hosts != sorted_hosts)
tapted 2016/03/15 22:54:53 nit: need curlies (policy is if the body is multi
kirr 2016/03/16 21:43:45 Done. Thanks.
+ [widget->GetNativeView() sortSubviewsUsingFunction:&SubviewSorter
tapted 2016/03/15 22:54:53 If we are worried about using this function in par
kirr 2016/03/16 21:43:45 Seems like it's better not worry about it until we
+ context:&sorted_hosts];
+}
+
+} // namespace views
« no previous file with comments | « ui/views/widget/widget_mac_utils.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698