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

Side by Side Diff: chrome/browser/ui/ash/multi_user_window_manager.cc

Issue 55303003: Fixing drag and drop visibility issues of tabs on a visiting desktop (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: . Created 7 years, 1 month 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 | Annotate | Revision Log
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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 "chrome/browser/ui/ash/multi_user_window_manager.h" 5 #include "chrome/browser/ui/ash/multi_user_window_manager.h"
6 6
7 #include "apps/shell_window.h" 7 #include "apps/shell_window.h"
8 #include "apps/shell_window_registry.h" 8 #include "apps/shell_window_registry.h"
9 #include "ash/ash_switches.h" 9 #include "ash/ash_switches.h"
10 #include "ash/session_state_delegate.h" 10 #include "ash/session_state_delegate.h"
11 #include "ash/shell.h" 11 #include "ash/shell.h"
12 #include "ash/shell_delegate.h" 12 #include "ash/shell_delegate.h"
13 #include "ash/wm/mru_window_tracker.h" 13 #include "ash/wm/mru_window_tracker.h"
14 #include "ash/wm/window_positioner.h" 14 #include "ash/wm/window_positioner.h"
15 #include "ash/wm/window_state.h" 15 #include "ash/wm/window_state.h"
16 #include "base/auto_reset.h" 16 #include "base/auto_reset.h"
17 #include "base/message_loop/message_loop.h"
17 #include "base/strings/string_util.h" 18 #include "base/strings/string_util.h"
18 #include "chrome/browser/browser_process.h" 19 #include "chrome/browser/browser_process.h"
19 #include "chrome/browser/chrome_notification_types.h" 20 #include "chrome/browser/chrome_notification_types.h"
20 #include "chrome/browser/chromeos/login/user_manager.h" 21 #include "chrome/browser/chromeos/login/user_manager.h"
21 #include "chrome/browser/profiles/profile.h" 22 #include "chrome/browser/profiles/profile.h"
22 #include "chrome/browser/profiles/profile_manager.h" 23 #include "chrome/browser/profiles/profile_manager.h"
23 #include "chrome/browser/ui/browser.h" 24 #include "chrome/browser/ui/browser.h"
24 #include "chrome/browser/ui/browser_list.h" 25 #include "chrome/browser/ui/browser_list.h"
25 #include "chrome/browser/ui/browser_window.h" 26 #include "chrome/browser/ui/browser_window.h"
26 #include "content/public/browser/notification_service.h" 27 #include "content/public/browser/notification_service.h"
27 #include "google_apis/gaia/gaia_auth_util.h" 28 #include "google_apis/gaia/gaia_auth_util.h"
28 #include "ui/aura/client/activation_client.h" 29 #include "ui/aura/client/activation_client.h"
29 #include "ui/aura/client/aura_constants.h" 30 #include "ui/aura/client/aura_constants.h"
30 #include "ui/aura/root_window.h" 31 #include "ui/aura/root_window.h"
31 #include "ui/aura/window.h" 32 #include "ui/aura/window.h"
32 #include "ui/base/ui_base_types.h" 33 #include "ui/base/ui_base_types.h"
34 #include "ui/events/event.h"
33 35
34 namespace { 36 namespace {
35 chrome::MultiUserWindowManager* g_instance = NULL; 37 chrome::MultiUserWindowManager* g_instance = NULL;
38
39
40 // Checks if a given event is a user event.
41 bool IsUserEvent(ui::Event* e) {
42 if (e) {
43 ui::EventType type = e->type();
44 if (type != ui::ET_CANCEL_MODE &&
45 type != ui::ET_UMA_DATA &&
46 type != ui::ET_UNKNOWN)
47 return true;
48 }
49 return false;
50 }
51
52 // Test if we are currently processing a user event which might lead to a
53 // browser / app creation.
54 bool IsProcessingUserEvent() {
55 // When there is a nested message loop (e.g. active menu or drag and drop
56 // operation) - we are in a nested loop and can ignore this.
57 // Note: Unit tests might not have a message loop.
58 base::MessageLoop* message_loop = base::MessageLoop::current();
59 if (message_loop && message_loop->is_running() && message_loop->IsNested())
60 return false;
61
62 // TODO(skuhne): "Open link in new window" will come here after the menu got
63 // closed, executing the command from the nested menu loop. However at that
64 // time there is no active event processed. A solution for that need to be
65 // found past M-32. A global event handler filter (pre and post) might fix
66 // that problem in conjunction with a depth counter - but - for the menu
67 // execution we come here after the loop was finished (so it's not nested
68 // anymore) and the root window should therefore still have the event which
69 // lead to the menu invocation, but it is not. By fixing that problem this
70 // would "magically work".
71 ash::Shell::RootWindowList root_window_list = ash::Shell::GetAllRootWindows();
72 for (ash::Shell::RootWindowList::iterator it = root_window_list.begin();
73 it != root_window_list.end();
74 ++it) {
75 if (IsUserEvent((*it)->current_event()))
76 return true;
77 }
78 return false;
79 }
80
36 } // namespace 81 } // namespace
37 82
38 namespace chrome { 83 namespace chrome {
39 84
40 // Caching the current multi profile mode since the detection which mode is 85 // Caching the current multi profile mode since the detection which mode is
41 // used is quite expensive. 86 // used is quite expensive.
42 chrome::MultiUserWindowManager::MultiProfileMode 87 chrome::MultiUserWindowManager::MultiProfileMode
43 chrome::MultiUserWindowManager::multi_user_mode_ = 88 chrome::MultiUserWindowManager::multi_user_mode_ =
44 chrome::MultiUserWindowManager::MULTI_PROFILE_MODE_UNINITIALIZED; 89 chrome::MultiUserWindowManager::MULTI_PROFILE_MODE_UNINITIALIZED;
45 90
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
161 void MultiUserWindowManager::SetWindowOwner(aura::Window* window, 206 void MultiUserWindowManager::SetWindowOwner(aura::Window* window,
162 const std::string& user_id) { 207 const std::string& user_id) {
163 // Make sure the window is valid and there was no owner yet. 208 // Make sure the window is valid and there was no owner yet.
164 DCHECK(window); 209 DCHECK(window);
165 DCHECK(!user_id.empty()); 210 DCHECK(!user_id.empty());
166 if (GetWindowOwner(window) == user_id) 211 if (GetWindowOwner(window) == user_id)
167 return; 212 return;
168 DCHECK(GetWindowOwner(window).empty()); 213 DCHECK(GetWindowOwner(window).empty());
169 window_to_entry_[window] = new WindowEntry(user_id); 214 window_to_entry_[window] = new WindowEntry(user_id);
170 215
216 // Remember the initial visibility of the window.
217 window_to_entry_[window]->set_show(window->IsVisible());
218
171 // Set the window and the state observer. 219 // Set the window and the state observer.
172 window->AddObserver(this); 220 window->AddObserver(this);
173 ash::wm::GetWindowState(window)->AddObserver(this); 221 ash::wm::GetWindowState(window)->AddObserver(this);
174 222
223 // Check if this window was created due to a user interaction. If it was,
224 // transfer it to the current user.
225 if (IsProcessingUserEvent())
226 window_to_entry_[window]->set_show_for_user(current_user_id_);
227
175 // Add all transient children to our set of windows. Note that the function 228 // Add all transient children to our set of windows. Note that the function
176 // will add the children but not the owner to the transient children map. 229 // will add the children but not the owner to the transient children map.
177 AddTransientOwnerRecursive(window, window); 230 AddTransientOwnerRecursive(window, window);
178 231
179 if (user_id != current_user_id_) 232 if (!IsWindowOnDesktopOfUser(window, current_user_id_))
180 SetWindowVisibility(window, false); 233 SetWindowVisibility(window, false);
181 } 234 }
182 235
183 const std::string& MultiUserWindowManager::GetWindowOwner( 236 const std::string& MultiUserWindowManager::GetWindowOwner(
184 aura::Window* window) { 237 aura::Window* window) {
185 WindowToEntryMap::iterator it = window_to_entry_.find(window); 238 WindowToEntryMap::iterator it = window_to_entry_.find(window);
186 return it != window_to_entry_.end() ? it->second->owner() : EmptyString(); 239 return it != window_to_entry_.end() ? it->second->owner() : EmptyString();
187 } 240 }
188 241
189 void MultiUserWindowManager::ShowWindowForUser(aura::Window* window, 242 void MultiUserWindowManager::ShowWindowForUser(aura::Window* window,
190 const std::string& user_id) { 243 const std::string& user_id) {
191 // If there is either no owner, or the owner is the current user, no action 244 // If there is either no owner, or the owner is the current user, no action
192 // is required. 245 // is required.
193 const std::string& owner = GetWindowOwner(window); 246 const std::string& owner = GetWindowOwner(window);
194 if (owner.empty() || 247 if (owner.empty() ||
195 (owner == user_id && IsWindowOnDesktopOfUser(window, user_id))) 248 (owner == user_id && IsWindowOnDesktopOfUser(window, user_id)))
196 return; 249 return;
197 250
198 // Check that we are not trying to transfer ownership of a minimized window. 251 // Check that we are not trying to transfer ownership of a minimized window.
199 if (user_id != owner && ash::wm::GetWindowState(window)->IsMinimized()) 252 if (user_id != owner && ash::wm::GetWindowState(window)->IsMinimized())
200 return; 253 return;
201 254
202 WindowToEntryMap::iterator it = window_to_entry_.find(window); 255 WindowToEntryMap::iterator it = window_to_entry_.find(window);
203 it->second->set_show_for_user(user_id); 256 it->second->set_show_for_user(user_id);
204 257
205 // Show the window if the added user is the current one. 258 // Show the window if the added user is the current one.
206 if (user_id == current_user_id_) 259 if (user_id == current_user_id_) {
207 SetWindowVisibility(window, true); 260 // Only show the window if it should be shown according to its state.
208 else 261 if (it->second->show())
262 SetWindowVisibility(window, true);
263 } else {
209 SetWindowVisibility(window, false); 264 SetWindowVisibility(window, false);
265 }
210 } 266 }
211 267
212 bool MultiUserWindowManager::AreWindowsSharedAmongUsers() { 268 bool MultiUserWindowManager::AreWindowsSharedAmongUsers() {
213 WindowToEntryMap::iterator it = window_to_entry_.begin(); 269 WindowToEntryMap::iterator it = window_to_entry_.begin();
214 for (; it != window_to_entry_.end(); ++it) { 270 for (; it != window_to_entry_.end(); ++it) {
215 if (it->second->owner() != it->second->show_for_user()) 271 if (it->second->owner() != it->second->show_for_user())
216 return true; 272 return true;
217 } 273 }
218 return false; 274 return false;
219 } 275 }
(...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after
485 541
486 void MultiUserWindowManager::SetWindowVisibility( 542 void MultiUserWindowManager::SetWindowVisibility(
487 aura::Window* window, bool visible) { 543 aura::Window* window, bool visible) {
488 if (window->IsVisible() == visible) 544 if (window->IsVisible() == visible)
489 return; 545 return;
490 546
491 // To avoid that these commands are recorded as any other commands, we are 547 // To avoid that these commands are recorded as any other commands, we are
492 // suppressing any window entry changes while this is going on. 548 // suppressing any window entry changes while this is going on.
493 base::AutoReset<bool> suppressor(&suppress_visibility_changes_, true); 549 base::AutoReset<bool> suppressor(&suppress_visibility_changes_, true);
494 550
495 if (visible) 551 if (visible) {
496 ShowWithTransientChildrenRecursive(window); 552 ShowWithTransientChildrenRecursive(window);
497 else 553 } else {
554 if (window->HasFocus())
555 window->Blur();
498 window->Hide(); 556 window->Hide();
557 }
499 } 558 }
500 559
501 void MultiUserWindowManager::ShowWithTransientChildrenRecursive( 560 void MultiUserWindowManager::ShowWithTransientChildrenRecursive(
502 aura::Window* window) { 561 aura::Window* window) {
503 aura::Window::Windows::const_iterator it = 562 aura::Window::Windows::const_iterator it =
504 window->transient_children().begin(); 563 window->transient_children().begin();
505 for (; it != window->transient_children().end(); ++it) 564 for (; it != window->transient_children().end(); ++it)
506 ShowWithTransientChildrenRecursive(*it); 565 ShowWithTransientChildrenRecursive(*it);
507 566
508 // We show all children which were not explicitly hidden. 567 // We show all children which were not explicitly hidden.
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
576 // To prevent these commands from being recorded as any other commands, we 635 // To prevent these commands from being recorded as any other commands, we
577 // are suppressing any window entry changes while this is going on. 636 // are suppressing any window entry changes while this is going on.
578 // Instead of calling SetWindowVisible, only show gets called here since all 637 // Instead of calling SetWindowVisible, only show gets called here since all
579 // dependents have been shown previously already. 638 // dependents have been shown previously already.
580 base::AutoReset<bool> suppressor(&suppress_visibility_changes_, true); 639 base::AutoReset<bool> suppressor(&suppress_visibility_changes_, true);
581 window->Show(); 640 window->Show();
582 } 641 }
583 } 642 }
584 643
585 } // namespace chrome 644 } // namespace chrome
OLDNEW
« no previous file with comments | « chrome/browser/ui/ash/launcher/browser_status_monitor.cc ('k') | chrome/browser/ui/ash/multi_user_window_manager_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698