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

Side by Side Diff: components/mus/common/transient_window_utils.h

Issue 2119963002: Move mus to //services/ui (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: . Created 4 years, 5 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/mus/common/switches.cc ('k') | components/mus/common/types.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #ifndef COMPONENTS_MUS_COMMON_TRANSIENT_WINDOW_UTILS_H_
6 #define COMPONENTS_MUS_COMMON_TRANSIENT_WINDOW_UTILS_H_
7
8 #include <stddef.h>
9
10 #include <vector>
11
12 #include "components/mus/public/interfaces/mus_constants.mojom.h"
13
14 namespace mus {
15
16 // Returns true if |window| has |ancestor| as a transient ancestor. A transient
17 // ancestor is found by following the transient parent chain of the window.
18 template <class T>
19 bool HasTransientAncestor(const T* window, const T* ancestor) {
20 const T* transient_parent = window->transient_parent();
21 if (transient_parent == ancestor)
22 return true;
23 return transient_parent ? HasTransientAncestor(transient_parent, ancestor)
24 : false;
25 }
26
27 // Populates |ancestors| with all transient ancestors of |window| that are
28 // siblings of |window|. Returns true if any ancestors were found, false if not.
29 template <class T>
30 bool GetAllTransientAncestors(T* window, std::vector<T*>* ancestors) {
31 T* parent = window->parent();
32 for (; window; window = window->transient_parent()) {
33 if (window->parent() == parent)
34 ancestors->push_back(window);
35 }
36 return !ancestors->empty();
37 }
38
39 // Replaces |window1| and |window2| with their possible transient ancestors that
40 // are still siblings (have a common transient parent). |window1| and |window2|
41 // are not modified if such ancestors cannot be found.
42 template <class T>
43 void FindCommonTransientAncestor(T** window1, T** window2) {
44 DCHECK(window1);
45 DCHECK(window2);
46 DCHECK(*window1);
47 DCHECK(*window2);
48 // Assemble chains of ancestors of both windows.
49 std::vector<T*> ancestors1;
50 std::vector<T*> ancestors2;
51 if (!GetAllTransientAncestors(*window1, &ancestors1) ||
52 !GetAllTransientAncestors(*window2, &ancestors2)) {
53 return;
54 }
55 // Walk the two chains backwards and look for the first difference.
56 auto it1 = ancestors1.rbegin();
57 auto it2 = ancestors2.rbegin();
58 for (; it1 != ancestors1.rend() && it2 != ancestors2.rend(); ++it1, ++it2) {
59 if (*it1 != *it2) {
60 *window1 = *it1;
61 *window2 = *it2;
62 break;
63 }
64 }
65 }
66
67 template <class T>
68 bool AdjustStackingForTransientWindows(T** child,
69 T** target,
70 mojom::OrderDirection* direction,
71 T* stacking_target) {
72 if (stacking_target == *target)
73 return true;
74
75 // For windows that have transient children stack the transient ancestors that
76 // are siblings. This prevents one transient group from being inserted in the
77 // middle of another.
78 FindCommonTransientAncestor(child, target);
79
80 // When stacking above skip to the topmost transient descendant of the target.
81 if (*direction == mojom::OrderDirection::ABOVE &&
82 !HasTransientAncestor(*child, *target)) {
83 const std::vector<T*>& siblings((*child)->parent()->children());
84 size_t target_i =
85 std::find(siblings.begin(), siblings.end(), *target) - siblings.begin();
86 while (target_i + 1 < siblings.size() &&
87 HasTransientAncestor(siblings[target_i + 1], *target)) {
88 ++target_i;
89 }
90 *target = siblings[target_i];
91 }
92
93 return *child != *target;
94 }
95
96 // Stacks transient descendants of |window| that are its siblings just above it.
97 // |GetStackingTarget| is a function that returns a marker associated with a
98 // Window that indicates the current Window being stacked.
99 // |Reorder| is a function that takes in two windows and orders the first
100 // relative to the second based on the provided OrderDirection.
101 template <class T>
102 void RestackTransientDescendants(T* window,
103 T** (*GetStackingTarget)(T*),
104 void (*Reorder)(T*,
105 T*,
106 mojom::OrderDirection)) {
107 T* parent = window->parent();
108 if (!parent)
109 return;
110
111 // stack any transient children that share the same parent to be in front of
112 // |window_|. the existing stacking order is preserved by iterating backwards
113 // and always stacking on top.
114 std::vector<T*> children(parent->children());
115 for (auto it = children.rbegin(); it != children.rend(); ++it) {
116 if ((*it) != window && HasTransientAncestor(*it, window)) {
117 T* old_stacking_target = *GetStackingTarget(*it);
118 *GetStackingTarget(*it) = window;
119 Reorder(*it, window, mojom::OrderDirection::ABOVE);
120 *GetStackingTarget(*it) = old_stacking_target;
121 }
122 }
123 }
124 } // namespace mus
125
126 #endif // COMPONENTS_MUS_COMMON_TRANSIENT_WINDOW_UTILS_H_
OLDNEW
« no previous file with comments | « components/mus/common/switches.cc ('k') | components/mus/common/types.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698