File: window_controller_list.cc

package info (click to toggle)
chromium 145.0.7632.159-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 5,976,224 kB
  • sloc: cpp: 36,198,469; ansic: 7,634,080; javascript: 3,564,060; python: 1,649,622; xml: 838,470; asm: 717,087; pascal: 185,708; sh: 88,786; perl: 88,718; objc: 79,984; sql: 59,811; cs: 42,452; fortran: 24,101; makefile: 21,144; tcl: 15,277; php: 14,022; yacc: 9,066; ruby: 7,553; awk: 3,720; lisp: 3,233; lex: 1,328; ada: 727; jsp: 228; sed: 36
file content (131 lines) | stat: -rw-r--r-- 4,350 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/extensions/window_controller_list.h"

#include <algorithm>

#include "base/containers/contains.h"
#include "base/observer_list.h"
#include "chrome/browser/extensions/api/tabs/windows_util.h"
#include "chrome/browser/extensions/window_controller_list_observer.h"
#include "chrome/common/extensions/api/windows.h"
#include "components/sessions/core/session_id.h"
#include "extensions/browser/extension_function.h"
#include "extensions/buildflags/buildflags.h"
#include "ui/base/base_window.h"

static_assert(BUILDFLAG(ENABLE_EXTENSIONS_CORE));

namespace extensions {

///////////////////////////////////////////////////////////////////////////////
// WindowControllerList

// static
WindowControllerList* WindowControllerList::GetInstance() {
  return base::Singleton<WindowControllerList>::get();
}

WindowControllerList::WindowControllerList() = default;

WindowControllerList::~WindowControllerList() = default;

void WindowControllerList::AddExtensionWindow(WindowController* window) {
  windows_.push_back(window);
  for (auto& observer : observers_)
    observer.OnWindowControllerAdded(window);
}

void WindowControllerList::RemoveExtensionWindow(WindowController* window) {
  auto iter = std::ranges::find(windows_, window);
  if (iter != windows_.end()) {
    windows_.erase(iter);
    for (auto& observer : observers_)
      observer.OnWindowControllerRemoved(window);
  }
}

void WindowControllerList::NotifyWindowBoundsChanged(WindowController* window) {
  if (base::Contains(windows_, window)) {
    for (auto& observer : observers_)
      observer.OnWindowBoundsChanged(window);
  }
}

void WindowControllerList::NotifyWindowFocusChanged(WindowController* window,
                                                    bool has_focus) {
  if (base::Contains(windows_, window)) {
    for (auto& observer : observers_) {
      observer.OnWindowFocusChanged(window, has_focus);
    }
  }
}

void WindowControllerList::AddObserver(WindowControllerListObserver* observer) {
  observers_.AddObserver(observer);
}

void WindowControllerList::RemoveObserver(
    WindowControllerListObserver* observer) {
  observers_.RemoveObserver(observer);
}

WindowController* WindowControllerList::FindWindowForFunctionByIdWithFilter(
    const ExtensionFunction* function,
    int id,
    WindowController::TypeFilter filter) const {
  for (auto iter = windows_.begin(); iter != windows_.end(); ++iter) {
    if ((*iter)->GetWindowId() == id) {
      if (windows_util::CanOperateOnWindow(function, *iter, filter))
        return *iter;
      return nullptr;
    }
  }
  return nullptr;
}

WindowController* WindowControllerList::CurrentWindowForFunction(
    ExtensionFunction* function) const {
  return CurrentWindowForFunctionWithFilter(function,
                                            WindowController::kNoWindowFilter);
}

WindowController* WindowControllerList::CurrentWindowForFunctionWithFilter(
    ExtensionFunction* function,
    WindowController::TypeFilter filter) const {
  // Always prefer the focused window if available. If there is no focused
  // window, prefer the window to which the sender window is logically parented.
  // Since the browser window is not "focused" when an extension popup is open
  // (because popup is hosted in a separate window, which is focused instead),
  // we need to check for the logical parent window here. If neither of these
  // are available, return the last window.
  WindowController* last_window = nullptr;
  WindowController* parent_window = nullptr;

  for (const auto& controller : windows_) {
    if (!windows_util::CanOperateOnWindow(function, controller, filter)) {
      continue;
    }

    if (controller->window()->IsActive()) {
      // If the window is focused, return it immediately.
      return controller;
    }

#if !BUILDFLAG(IS_ANDROID)
    // TODO(crbug.com/371432155): Support on Android.
    // windows_util::CalledFromChildWindow() checks native widgets for parents.
    if (windows_util::CalledFromChildWindow(function, controller)) {
      parent_window = controller;
    }
#endif

    last_window = controller;
  }

  return parent_window ? parent_window : last_window;
}

}  // namespace extensions