[email protected] | 9704519 | 2012-03-09 20:53:59 | [diff] [blame] | 1 | // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
[email protected] | 052313b | 2010-02-19 09:43:08 | [diff] [blame] | 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
[email protected] | 609eeec2 | 2009-05-10 06:21:49 | [diff] [blame] | 4 | |
[email protected] | 9e790bd | 2011-01-10 23:48:54 | [diff] [blame] | 5 | #include "chrome/browser/ui/views/chrome_views_delegate.h" |
[email protected] | 609eeec2 | 2009-05-10 06:21:49 | [diff] [blame] | 6 | |
dcheng | 9603ab9 | 2016-04-08 04:17:32 | [diff] [blame] | 7 | #include <memory> |
| 8 | |
fdoray | 6be72ad | 2016-06-16 17:46:41 | [diff] [blame] | 9 | #include "base/location.h" |
fdoray | 19e49e9 | 2016-09-30 20:42:16 | [diff] [blame] | 10 | #include "base/logging.h" |
fdoray | 6be72ad | 2016-06-16 17:46:41 | [diff] [blame] | 11 | #include "base/message_loop/message_loop.h" |
fdoray | 283082bd | 2016-06-02 20:18:46 | [diff] [blame] | 12 | #include "base/single_thread_task_runner.h" |
[email protected] | 2ff32055 | 2013-06-10 22:53:18 | [diff] [blame] | 13 | #include "base/strings/string_util.h" |
[email protected] | 774cc3c | 2013-06-07 20:26:45 | [diff] [blame] | 14 | #include "base/strings/utf_string_conversions.h" |
fdoray | 19e49e9 | 2016-09-30 20:42:16 | [diff] [blame] | 15 | #include "base/threading/thread_task_runner_handle.h" |
[email protected] | b22b27a | 2013-06-28 05:37:57 | [diff] [blame] | 16 | #include "base/time/time.h" |
avi | 202f340 | 2015-12-24 23:54:45 | [diff] [blame] | 17 | #include "build/build_config.h" |
[email protected] | 609eeec2 | 2009-05-10 06:21:49 | [diff] [blame] | 18 | #include "chrome/browser/browser_process.h" |
dgn | fe075c8 | 2016-03-18 11:25:35 | [diff] [blame] | 19 | #include "chrome/browser/lifetime/keep_alive_types.h" |
| 20 | #include "chrome/browser/lifetime/scoped_keep_alive.h" |
[email protected] | f87919d7 | 2011-02-02 18:46:16 | [diff] [blame] | 21 | #include "chrome/browser/profiles/profile_manager.h" |
staraz | 92c518d | 2016-06-20 18:07:46 | [diff] [blame] | 22 | #include "chrome/browser/ui/ash/ash_util.h" |
dgrogan | e30f8f0 | 2014-09-16 22:41:08 | [diff] [blame] | 23 | #include "chrome/browser/ui/browser_window_state.h" |
ellyjones | 50ef64e | 2016-11-22 19:48:13 | [diff] [blame] | 24 | #include "chrome/browser/ui/views/harmony/harmony_layout_delegate.h" |
thestig | 4a9b0ef | 2016-08-29 08:22:12 | [diff] [blame] | 25 | #include "chrome/grit/chrome_unscaled_resources.h" |
brettw | b1fc1b8 | 2016-02-02 00:19:08 | [diff] [blame] | 26 | #include "components/prefs/pref_service.h" |
| 27 | #include "components/prefs/scoped_user_pref_update.h" |
sdefresne | 9fb6769 | 2015-08-03 18:48:22 | [diff] [blame] | 28 | #include "components/version_info/version_info.h" |
dmazzoni | b9bfea77 | 2015-04-27 21:12:45 | [diff] [blame] | 29 | #include "content/public/browser/browser_thread.h" |
tapted | 36ffc47 | 2014-11-11 22:17:04 | [diff] [blame] | 30 | #include "content/public/browser/context_factory.h" |
ellyjones | 50ef64e | 2016-11-22 19:48:13 | [diff] [blame] | 31 | #include "ui/base/material_design/material_design_controller.h" |
[email protected] | 4af13c72 | 2013-11-13 21:16:39 | [diff] [blame] | 32 | #include "ui/base/resource/resource_bundle.h" |
[email protected] | 0a2703fd | 2013-04-12 16:14:08 | [diff] [blame] | 33 | #include "ui/base/ui_base_switches.h" |
oshima | 888290a | 2016-05-13 20:36:06 | [diff] [blame] | 34 | #include "ui/display/display.h" |
oshima | d5c972e | 2016-04-28 23:17:14 | [diff] [blame] | 35 | #include "ui/display/screen.h" |
tfarina | 3b0452d | 2014-12-31 15:20:09 | [diff] [blame] | 36 | #include "ui/gfx/geometry/rect.h" |
afakhry | 692024d9 | 2015-09-14 17:07:38 | [diff] [blame] | 37 | #include "ui/views/controls/menu/menu_controller.h" |
[email protected] | c13be0d | 2011-11-22 02:09:58 | [diff] [blame] | 38 | #include "ui/views/widget/native_widget.h" |
| 39 | #include "ui/views/widget/widget.h" |
[email protected] | 609eeec2 | 2009-05-10 06:21:49 | [diff] [blame] | 40 | |
[email protected] | f7be2197b | 2010-04-23 00:20:44 | [diff] [blame] | 41 | #if defined(OS_WIN) |
[email protected] | 0f440df | 2013-04-02 07:43:22 | [diff] [blame] | 42 | #include <dwmapi.h> |
[email protected] | 05ac311a | 2014-04-22 20:49:35 | [diff] [blame] | 43 | #include <shellapi.h> |
robliao | cc68a9f | 2015-02-27 03:36:22 | [diff] [blame] | 44 | #include "base/profiler/scoped_tracker.h" |
[email protected] | 6c52fef | 2014-04-22 20:26:53 | [diff] [blame] | 45 | #include "base/task_runner_util.h" |
[email protected] | 0f440df | 2013-04-02 07:43:22 | [diff] [blame] | 46 | #include "base/win/windows_version.h" |
pmonette | 23c8fb7e | 2016-06-27 20:45:11 | [diff] [blame] | 47 | #include "chrome/browser/win/app_icon.h" |
[email protected] | 9a8a76d | 2013-06-29 13:02:15 | [diff] [blame] | 48 | #include "ui/base/win/shell.h" |
[email protected] | f7be2197b | 2010-04-23 00:20:44 | [diff] [blame] | 49 | #endif |
| 50 | |
[email protected] | 2a2caa0 | 2013-01-22 20:50:36 | [diff] [blame] | 51 | #if defined(USE_AURA) |
dtseng | 22fad8b | 2015-03-30 21:45:57 | [diff] [blame] | 52 | #include "chrome/browser/ui/aura/accessibility/automation_manager_aura.h" |
[email protected] | 98e0f096 | 2014-04-24 23:42:11 | [diff] [blame] | 53 | #include "ui/aura/window.h" |
[email protected] | fcc51c95 | 2014-02-21 21:31:26 | [diff] [blame] | 54 | #include "ui/aura/window_event_dispatcher.h" |
[email protected] | 2a2caa0 | 2013-01-22 20:50:36 | [diff] [blame] | 55 | #endif |
| 56 | |
[email protected] | 2f0dcb6 | 2012-09-13 22:49:51 | [diff] [blame] | 57 | #if defined(USE_AURA) && !defined(OS_CHROMEOS) |
[email protected] | 0295754 | 2012-11-13 20:41:23 | [diff] [blame] | 58 | #include "ui/views/widget/desktop_aura/desktop_native_widget_aura.h" |
[email protected] | 80eb77bd | 2012-10-05 20:20:21 | [diff] [blame] | 59 | #include "ui/views/widget/native_widget_aura.h" |
[email protected] | 2f0dcb6 | 2012-09-13 22:49:51 | [diff] [blame] | 60 | #endif |
| 61 | |
[email protected] | 02abfee | 2014-01-23 09:27:02 | [diff] [blame] | 62 | #if defined(OS_LINUX) && !defined(OS_CHROMEOS) |
| 63 | #include "ui/views/linux_ui/linux_ui.h" |
| 64 | #endif |
| 65 | |
[email protected] | 9704519 | 2012-03-09 20:53:59 | [diff] [blame] | 66 | #if defined(USE_ASH) |
brettw | 08fe0e95 | 2016-08-26 21:53:39 | [diff] [blame] | 67 | #include "ash/common/accelerators/accelerator_controller.h" // nogncheck |
| 68 | #include "ash/common/wm/window_state.h" // nogncheck |
| 69 | #include "ash/common/wm_shell.h" // nogncheck |
| 70 | #include "ash/shell.h" // nogncheck |
| 71 | #include "ash/wm/window_state_aura.h" // nogncheck |
| 72 | #include "chrome/browser/ui/ash/ash_init.h" // nogncheck |
[email protected] | 57b8bb35 | 2012-01-11 05:11:46 | [diff] [blame] | 73 | #endif |
| 74 | |
[email protected] | e9fe851 | 2014-04-21 21:27:08 | [diff] [blame] | 75 | // Helpers -------------------------------------------------------------------- |
| 76 | |
[email protected] | f87919d7 | 2011-02-02 18:46:16 | [diff] [blame] | 77 | namespace { |
| 78 | |
[email protected] | ec9738b | 2014-04-20 21:56:00 | [diff] [blame] | 79 | Profile* GetProfileForWindow(const views::Widget* window) { |
| 80 | if (!window) |
| 81 | return NULL; |
| 82 | return reinterpret_cast<Profile*>( |
| 83 | window->GetNativeWindowProperty(Profile::kProfileKey)); |
| 84 | } |
| 85 | |
[email protected] | 28aec9a | 2011-02-04 13:45:11 | [diff] [blame] | 86 | // If the given window has a profile associated with it, use that profile's |
| 87 | // preference service. Otherwise, store and retrieve the data from Local State. |
| 88 | // This function may return NULL if the necessary pref service has not yet |
| 89 | // been initialized. |
| 90 | // TODO(mirandac): This function will also separate windows by profile in a |
| 91 | // multi-profile environment. |
[email protected] | 0c2830d | 2011-08-26 18:05:09 | [diff] [blame] | 92 | PrefService* GetPrefsForWindow(const views::Widget* window) { |
[email protected] | ec9738b | 2014-04-20 21:56:00 | [diff] [blame] | 93 | Profile* profile = GetProfileForWindow(window); |
[email protected] | 28aec9a | 2011-02-04 13:45:11 | [diff] [blame] | 94 | if (!profile) { |
| 95 | // Use local state for windows that have no explicit profile. |
[email protected] | f87919d7 | 2011-02-02 18:46:16 | [diff] [blame] | 96 | return g_browser_process->local_state(); |
[email protected] | f87919d7 | 2011-02-02 18:46:16 | [diff] [blame] | 97 | } |
[email protected] | 28aec9a | 2011-02-04 13:45:11 | [diff] [blame] | 98 | return profile->GetPrefs(); |
[email protected] | f87919d7 | 2011-02-02 18:46:16 | [diff] [blame] | 99 | } |
| 100 | |
[email protected] | 6c52fef | 2014-04-22 20:26:53 | [diff] [blame] | 101 | #if defined(OS_WIN) |
ananta | abe5bdc | 2016-12-03 03:32:47 | [diff] [blame] | 102 | bool MonitorHasAutohideTaskbarForEdge(UINT edge, HMONITOR monitor) { |
[email protected] | 51790445 | 2014-05-31 01:03:30 | [diff] [blame] | 103 | APPBARDATA taskbar_data = { sizeof(APPBARDATA), NULL, 0, edge }; |
ananta | c64c903 | 2015-11-23 21:28:27 | [diff] [blame] | 104 | taskbar_data.hWnd = ::GetForegroundWindow(); |
robliao | cc68a9f | 2015-02-27 03:36:22 | [diff] [blame] | 105 | |
| 106 | // TODO(robliao): Remove ScopedTracker below once crbug.com/462368 is fixed. |
| 107 | tracked_objects::ScopedTracker tracking_profile( |
| 108 | FROM_HERE_WITH_EXPLICIT_FUNCTION( |
ananta | abe5bdc | 2016-12-03 03:32:47 | [diff] [blame] | 109 | "462368 MonitorHasAutohideTaskbarForEdge")); |
robliao | cc68a9f | 2015-02-27 03:36:22 | [diff] [blame] | 110 | |
[email protected] | 51790445 | 2014-05-31 01:03:30 | [diff] [blame] | 111 | // MSDN documents an ABM_GETAUTOHIDEBAREX, which supposedly takes a monitor |
| 112 | // rect and returns autohide bars on that monitor. This sounds like a good |
| 113 | // idea for multi-monitor systems. Unfortunately, it appears to not work at |
| 114 | // least some of the time (erroneously returning NULL) and there's almost no |
| 115 | // online documentation or other sample code using it that suggests ways to |
ananta | c64c903 | 2015-11-23 21:28:27 | [diff] [blame] | 116 | // address this problem. We do the following:- |
| 117 | // 1. Use the ABM_GETAUTOHIDEBAR message. If it works, i.e. returns a valid |
| 118 | // window we are done. |
| 119 | // 2. If the ABM_GETAUTOHIDEBAR message does not work we query the auto hide |
| 120 | // state of the taskbar and then retrieve its position. That call returns |
| 121 | // the edge on which the taskbar is present. If it matches the edge we |
| 122 | // are looking for, we are done. |
[email protected] | 6c52fef | 2014-04-22 20:26:53 | [diff] [blame] | 123 | // NOTE: This call spins a nested message loop. |
[email protected] | 51790445 | 2014-05-31 01:03:30 | [diff] [blame] | 124 | HWND taskbar = reinterpret_cast<HWND>(SHAppBarMessage(ABM_GETAUTOHIDEBAR, |
[email protected] | 6c52fef | 2014-04-22 20:26:53 | [diff] [blame] | 125 | &taskbar_data)); |
ananta | c64c903 | 2015-11-23 21:28:27 | [diff] [blame] | 126 | if (!::IsWindow(taskbar)) { |
| 127 | APPBARDATA taskbar_data = { sizeof(APPBARDATA), 0, 0, 0}; |
| 128 | unsigned int taskbar_state = SHAppBarMessage(ABM_GETSTATE, |
| 129 | &taskbar_data); |
| 130 | if (!(taskbar_state & ABS_AUTOHIDE)) |
| 131 | return false; |
| 132 | |
| 133 | taskbar_data.hWnd = ::FindWindow(L"Shell_TrayWnd", NULL); |
| 134 | if (!::IsWindow(taskbar_data.hWnd)) |
| 135 | return false; |
| 136 | |
| 137 | SHAppBarMessage(ABM_GETTASKBARPOS, &taskbar_data); |
| 138 | if (taskbar_data.uEdge == edge) |
| 139 | taskbar = taskbar_data.hWnd; |
| 140 | } |
ananta | a25bf4f | 2016-02-25 20:38:13 | [diff] [blame] | 141 | |
ananta | abe5bdc | 2016-12-03 03:32:47 | [diff] [blame] | 142 | // There is a potential race condition here: |
| 143 | // 1. A maximized chrome window is fullscreened. |
| 144 | // 2. It is switched back to maximized. |
| 145 | // 3. In the process the window gets a WM_NCCACLSIZE message which calls us to |
| 146 | // get the autohide state. |
| 147 | // 4. The worker thread is invoked. It calls the API to get the autohide |
| 148 | // state. On Windows versions earlier than Windows 7, taskbars could |
| 149 | // easily be always on top or not. |
| 150 | // This meant that we only want to look for taskbars which have the topmost |
| 151 | // bit set. However this causes problems in cases where the window on the |
| 152 | // main thread is still in the process of switching away from fullscreen. |
| 153 | // In this case the taskbar might not yet have the topmost bit set. |
| 154 | // 5. The main thread resumes and does not leave space for the taskbar and |
| 155 | // hence it does not pop when hovered. |
| 156 | // |
| 157 | // To address point 4 above, it is best to not check for the WS_EX_TOPMOST |
| 158 | // window style on the taskbar, as starting from Windows 7, the topmost |
| 159 | // style is always set. We don't support XP and Vista anymore. |
| 160 | if (::IsWindow(taskbar)) { |
ananta | a25bf4f | 2016-02-25 20:38:13 | [diff] [blame] | 161 | if (MonitorFromWindow(taskbar, MONITOR_DEFAULTTONEAREST) == monitor) |
| 162 | return true; |
| 163 | // In some cases like when the autohide taskbar is on the left of the |
| 164 | // secondary monitor, the MonitorFromWindow call above fails to return the |
| 165 | // correct monitor the taskbar is on. We fallback to MonitorFromPoint for |
| 166 | // the cursor position in that case, which seems to work well. |
| 167 | POINT cursor_pos = {0}; |
| 168 | GetCursorPos(&cursor_pos); |
| 169 | if (MonitorFromPoint(cursor_pos, MONITOR_DEFAULTTONEAREST) == monitor) |
| 170 | return true; |
| 171 | } |
| 172 | return false; |
[email protected] | 6c52fef | 2014-04-22 20:26:53 | [diff] [blame] | 173 | } |
| 174 | |
| 175 | int GetAppbarAutohideEdgesOnWorkerThread(HMONITOR monitor) { |
| 176 | DCHECK(monitor); |
| 177 | |
[email protected] | 6c52fef | 2014-04-22 20:26:53 | [diff] [blame] | 178 | int edges = 0; |
ananta | abe5bdc | 2016-12-03 03:32:47 | [diff] [blame] | 179 | if (MonitorHasAutohideTaskbarForEdge(ABE_LEFT, monitor)) |
[email protected] | 6c52fef | 2014-04-22 20:26:53 | [diff] [blame] | 180 | edges |= views::ViewsDelegate::EDGE_LEFT; |
ananta | abe5bdc | 2016-12-03 03:32:47 | [diff] [blame] | 181 | if (MonitorHasAutohideTaskbarForEdge(ABE_TOP, monitor)) |
[email protected] | 6c52fef | 2014-04-22 20:26:53 | [diff] [blame] | 182 | edges |= views::ViewsDelegate::EDGE_TOP; |
ananta | abe5bdc | 2016-12-03 03:32:47 | [diff] [blame] | 183 | if (MonitorHasAutohideTaskbarForEdge(ABE_RIGHT, monitor)) |
[email protected] | 6c52fef | 2014-04-22 20:26:53 | [diff] [blame] | 184 | edges |= views::ViewsDelegate::EDGE_RIGHT; |
ananta | abe5bdc | 2016-12-03 03:32:47 | [diff] [blame] | 185 | if (MonitorHasAutohideTaskbarForEdge(ABE_BOTTOM, monitor)) |
[email protected] | 6c52fef | 2014-04-22 20:26:53 | [diff] [blame] | 186 | edges |= views::ViewsDelegate::EDGE_BOTTOM; |
| 187 | return edges; |
| 188 | } |
| 189 | #endif |
| 190 | |
afakhry | 692024d9 | 2015-09-14 17:07:38 | [diff] [blame] | 191 | #if defined(USE_ASH) |
| 192 | void ProcessAcceleratorNow(const ui::Accelerator& accelerator) { |
| 193 | // TODO(afakhry): See if we need here to send the accelerator to the |
| 194 | // FocusManager of the active window in a follow-up CL. |
sky | 89eb801 | 2016-07-22 03:28:31 | [diff] [blame] | 195 | ash::WmShell::Get()->accelerator_controller()->Process(accelerator); |
afakhry | 692024d9 | 2015-09-14 17:07:38 | [diff] [blame] | 196 | } |
| 197 | #endif // defined(USE_ASH) |
| 198 | |
[email protected] | f87919d7 | 2011-02-02 18:46:16 | [diff] [blame] | 199 | } // namespace |
| 200 | |
[email protected] | e9fe851 | 2014-04-21 21:27:08 | [diff] [blame] | 201 | |
| 202 | // ChromeViewsDelegate -------------------------------------------------------- |
| 203 | |
[email protected] | 6c52fef | 2014-04-22 20:26:53 | [diff] [blame] | 204 | #if defined(OS_WIN) |
| 205 | ChromeViewsDelegate::ChromeViewsDelegate() |
mohan.reddy | 1da4b61 | 2014-09-18 02:57:57 | [diff] [blame] | 206 | : in_autohide_edges_callback_(false), |
| 207 | weak_factory_(this) { |
[email protected] | 6c52fef | 2014-04-22 20:26:53 | [diff] [blame] | 208 | #else |
[email protected] | e9fe851 | 2014-04-21 21:27:08 | [diff] [blame] | 209 | ChromeViewsDelegate::ChromeViewsDelegate() { |
[email protected] | 6c52fef | 2014-04-22 20:26:53 | [diff] [blame] | 210 | #endif |
[email protected] | e9fe851 | 2014-04-21 21:27:08 | [diff] [blame] | 211 | } |
| 212 | |
| 213 | ChromeViewsDelegate::~ChromeViewsDelegate() { |
dgn | 6dd1bb2 | 2016-04-13 19:10:04 | [diff] [blame] | 214 | DCHECK_EQ(0u, ref_count_); |
[email protected] | e9fe851 | 2014-04-21 21:27:08 | [diff] [blame] | 215 | } |
[email protected] | 609eeec2 | 2009-05-10 06:21:49 | [diff] [blame] | 216 | |
[email protected] | 2fdd00a | 2011-06-13 21:56:26 | [diff] [blame] | 217 | void ChromeViewsDelegate::SaveWindowPlacement(const views::Widget* window, |
[email protected] | 660a3bc | 2011-09-16 18:40:55 | [diff] [blame] | 218 | const std::string& window_name, |
[email protected] | 609eeec2 | 2009-05-10 06:21:49 | [diff] [blame] | 219 | const gfx::Rect& bounds, |
[email protected] | 0fbe67bd | 2011-08-31 23:27:33 | [diff] [blame] | 220 | ui::WindowShowState show_state) { |
[email protected] | 0c2830d | 2011-08-26 18:05:09 | [diff] [blame] | 221 | PrefService* prefs = GetPrefsForWindow(window); |
[email protected] | f87919d7 | 2011-02-02 18:46:16 | [diff] [blame] | 222 | if (!prefs) |
[email protected] | 609eeec2 | 2009-05-10 06:21:49 | [diff] [blame] | 223 | return; |
| 224 | |
dcheng | 9603ab9 | 2016-04-08 04:17:32 | [diff] [blame] | 225 | std::unique_ptr<DictionaryPrefUpdate> pref_update = |
dgrogan | e30f8f0 | 2014-09-16 22:41:08 | [diff] [blame] | 226 | chrome::GetWindowPlacementDictionaryReadWrite(window_name, prefs); |
| 227 | base::DictionaryValue* window_preferences = pref_update->Get(); |
[email protected] | e219474 | 2010-08-12 05:54:34 | [diff] [blame] | 228 | window_preferences->SetInteger("left", bounds.x()); |
| 229 | window_preferences->SetInteger("top", bounds.y()); |
| 230 | window_preferences->SetInteger("right", bounds.right()); |
| 231 | window_preferences->SetInteger("bottom", bounds.bottom()); |
[email protected] | 0fbe67bd | 2011-08-31 23:27:33 | [diff] [blame] | 232 | window_preferences->SetBoolean("maximized", |
| 233 | show_state == ui::SHOW_STATE_MAXIMIZED); |
afakhry | 25a6b95 | 2017-01-27 20:36:50 | [diff] [blame^] | 234 | // TODO(afakhry): Remove Docked Windows in M58. |
varkha | 86fc7fe2 | 2015-07-10 20:36:41 | [diff] [blame] | 235 | window_preferences->SetBoolean("docked", show_state == ui::SHOW_STATE_DOCKED); |
afakhry | 25a6b95 | 2017-01-27 20:36:50 | [diff] [blame^] | 236 | |
oshima | d5c972e | 2016-04-28 23:17:14 | [diff] [blame] | 237 | gfx::Rect work_area(display::Screen::GetScreen() |
scottmg | fb33c34 | 2016-01-27 01:30:36 | [diff] [blame] | 238 | ->GetDisplayNearestWindow(window->GetNativeView()) |
| 239 | .work_area()); |
[email protected] | e219474 | 2010-08-12 05:54:34 | [diff] [blame] | 240 | window_preferences->SetInteger("work_area_left", work_area.x()); |
| 241 | window_preferences->SetInteger("work_area_top", work_area.y()); |
| 242 | window_preferences->SetInteger("work_area_right", work_area.right()); |
| 243 | window_preferences->SetInteger("work_area_bottom", work_area.bottom()); |
[email protected] | 609eeec2 | 2009-05-10 06:21:49 | [diff] [blame] | 244 | } |
| 245 | |
[email protected] | 0fbe67bd | 2011-08-31 23:27:33 | [diff] [blame] | 246 | bool ChromeViewsDelegate::GetSavedWindowPlacement( |
[email protected] | 0194049b | 2013-11-01 15:23:12 | [diff] [blame] | 247 | const views::Widget* widget, |
[email protected] | 660a3bc | 2011-09-16 18:40:55 | [diff] [blame] | 248 | const std::string& window_name, |
[email protected] | 0fbe67bd | 2011-08-31 23:27:33 | [diff] [blame] | 249 | gfx::Rect* bounds, |
| 250 | ui::WindowShowState* show_state) const { |
[email protected] | 6b823fc3 | 2011-07-14 23:05:16 | [diff] [blame] | 251 | PrefService* prefs = g_browser_process->local_state(); |
[email protected] | f87919d7 | 2011-02-02 18:46:16 | [diff] [blame] | 252 | if (!prefs) |
[email protected] | 609eeec2 | 2009-05-10 06:21:49 | [diff] [blame] | 253 | return false; |
| 254 | |
tfarina | 2b8c3763 | 2015-08-13 18:38:09 | [diff] [blame] | 255 | DCHECK(prefs->FindPreference(window_name)); |
| 256 | const base::DictionaryValue* dictionary = prefs->GetDictionary(window_name); |
[email protected] | 1d447bd9 | 2014-07-03 07:17:42 | [diff] [blame] | 257 | int left = 0; |
| 258 | int top = 0; |
| 259 | int right = 0; |
| 260 | int bottom = 0; |
[email protected] | e219474 | 2010-08-12 05:54:34 | [diff] [blame] | 261 | if (!dictionary || !dictionary->GetInteger("left", &left) || |
| 262 | !dictionary->GetInteger("top", &top) || |
| 263 | !dictionary->GetInteger("right", &right) || |
| 264 | !dictionary->GetInteger("bottom", &bottom)) |
[email protected] | 609eeec2 | 2009-05-10 06:21:49 | [diff] [blame] | 265 | return false; |
| 266 | |
| 267 | bounds->SetRect(left, top, right - left, bottom - top); |
[email protected] | 0fbe67bd | 2011-08-31 23:27:33 | [diff] [blame] | 268 | |
| 269 | bool maximized = false; |
| 270 | if (dictionary) |
| 271 | dictionary->GetBoolean("maximized", &maximized); |
| 272 | *show_state = maximized ? ui::SHOW_STATE_MAXIMIZED : ui::SHOW_STATE_NORMAL; |
| 273 | |
[email protected] | 0194049b | 2013-11-01 15:23:12 | [diff] [blame] | 274 | #if defined(USE_ASH) |
| 275 | // On Ash environment, a window won't span across displays. Adjust |
| 276 | // the bounds to fit the work area. |
| 277 | gfx::NativeView window = widget->GetNativeView(); |
oshima | d5c972e | 2016-04-28 23:17:14 | [diff] [blame] | 278 | display::Display display = |
| 279 | display::Screen::GetScreen()->GetDisplayMatching(*bounds); |
scottmg | e0c631f | 2016-02-20 06:16:29 | [diff] [blame] | 280 | bounds->AdjustToFit(display.work_area()); |
| 281 | ash::wm::GetWindowState(window)->set_minimum_visibility(true); |
[email protected] | 0194049b | 2013-11-01 15:23:12 | [diff] [blame] | 282 | #endif |
[email protected] | 609eeec2 | 2009-05-10 06:21:49 | [diff] [blame] | 283 | return true; |
| 284 | } |
| 285 | |
[email protected] | 6a054ffa | 2010-08-06 07:07:18 | [diff] [blame] | 286 | void ChromeViewsDelegate::NotifyAccessibilityEvent( |
[email protected] | 739c8bc | 2014-02-25 18:28:13 | [diff] [blame] | 287 | views::View* view, ui::AXEvent event_type) { |
dtseng | 22fad8b | 2015-03-30 21:45:57 | [diff] [blame] | 288 | #if defined(USE_AURA) |
| 289 | AutomationManagerAura::GetInstance()->HandleEvent( |
[email protected] | ec9738b | 2014-04-20 21:56:00 | [diff] [blame] | 290 | GetProfileForWindow(view->GetWidget()), view, event_type); |
[email protected] | 37ed14e | 2014-05-01 08:37:58 | [diff] [blame] | 291 | #endif |
[email protected] | 6a054ffa | 2010-08-06 07:07:18 | [diff] [blame] | 292 | } |
| 293 | |
afakhry | 692024d9 | 2015-09-14 17:07:38 | [diff] [blame] | 294 | views::ViewsDelegate::ProcessMenuAcceleratorResult |
| 295 | ChromeViewsDelegate::ProcessAcceleratorWhileMenuShowing( |
| 296 | const ui::Accelerator& accelerator) { |
| 297 | #if defined(USE_ASH) |
fdoray | 19e49e9 | 2016-09-30 20:42:16 | [diff] [blame] | 298 | DCHECK(base::MessageLoopForUI::IsCurrent()); |
| 299 | |
staraz | 92c518d | 2016-06-20 18:07:46 | [diff] [blame] | 300 | // Early return because mash chrome does not have access to ash::Shell |
| 301 | if (chrome::IsRunningInMash()) |
| 302 | return views::ViewsDelegate::ProcessMenuAcceleratorResult::LEAVE_MENU_OPEN; |
| 303 | |
afakhry | 692024d9 | 2015-09-14 17:07:38 | [diff] [blame] | 304 | ash::AcceleratorController* accelerator_controller = |
sky | 89eb801 | 2016-07-22 03:28:31 | [diff] [blame] | 305 | ash::WmShell::Get()->accelerator_controller(); |
afakhry | 692024d9 | 2015-09-14 17:07:38 | [diff] [blame] | 306 | |
| 307 | accelerator_controller->accelerator_history()->StoreCurrentAccelerator( |
| 308 | accelerator); |
| 309 | if (accelerator_controller->ShouldCloseMenuAndRepostAccelerator( |
| 310 | accelerator)) { |
fdoray | 19e49e9 | 2016-09-30 20:42:16 | [diff] [blame] | 311 | base::ThreadTaskRunnerHandle::Get()->PostTask( |
fdoray | 283082bd | 2016-06-02 20:18:46 | [diff] [blame] | 312 | FROM_HERE, base::Bind(ProcessAcceleratorNow, accelerator)); |
afakhry | 692024d9 | 2015-09-14 17:07:38 | [diff] [blame] | 313 | return views::ViewsDelegate::ProcessMenuAcceleratorResult::CLOSE_MENU; |
| 314 | } |
| 315 | |
| 316 | ProcessAcceleratorNow(accelerator); |
| 317 | return views::ViewsDelegate::ProcessMenuAcceleratorResult::LEAVE_MENU_OPEN; |
| 318 | #else |
| 319 | return views::ViewsDelegate::ProcessMenuAcceleratorResult::LEAVE_MENU_OPEN; |
| 320 | #endif // defined(USE_ASH) |
| 321 | } |
| 322 | |
[email protected] | 609eeec2 | 2009-05-10 06:21:49 | [diff] [blame] | 323 | #if defined(OS_WIN) |
| 324 | HICON ChromeViewsDelegate::GetDefaultWindowIcon() const { |
[email protected] | f7be2197b | 2010-04-23 00:20:44 | [diff] [blame] | 325 | return GetAppIcon(); |
[email protected] | 609eeec2 | 2009-05-10 06:21:49 | [diff] [blame] | 326 | } |
[email protected] | ceeed3b3 | 2013-12-03 21:46:53 | [diff] [blame] | 327 | |
tmoniuszko | cd5b3ee | 2014-12-15 08:51:04 | [diff] [blame] | 328 | HICON ChromeViewsDelegate::GetSmallWindowIcon() const { |
| 329 | return GetSmallAppIcon(); |
| 330 | } |
| 331 | |
[email protected] | 4af13c72 | 2013-11-13 21:16:39 | [diff] [blame] | 332 | #elif defined(OS_LINUX) && !defined(OS_CHROMEOS) |
| 333 | gfx::ImageSkia* ChromeViewsDelegate::GetDefaultWindowIcon() const { |
| 334 | ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); |
| 335 | return rb.GetImageSkiaNamed(IDR_PRODUCT_LOGO_64); |
| 336 | } |
[email protected] | 609eeec2 | 2009-05-10 06:21:49 | [diff] [blame] | 337 | #endif |
[email protected] | 365e821c | 2010-04-16 19:38:33 | [diff] [blame] | 338 | |
[email protected] | e9fe851 | 2014-04-21 21:27:08 | [diff] [blame] | 339 | #if defined(USE_ASH) |
[email protected] | 57b8bb35 | 2012-01-11 05:11:46 | [diff] [blame] | 340 | views::NonClientFrameView* ChromeViewsDelegate::CreateDefaultNonClientFrameView( |
| 341 | views::Widget* widget) { |
oshima | 4f791728 | 2016-05-10 11:25:03 | [diff] [blame] | 342 | return ash::Shell::GetInstance()->CreateDefaultNonClientFrameView(widget); |
[email protected] | 57b8bb35 | 2012-01-11 05:11:46 | [diff] [blame] | 343 | } |
[email protected] | e9fe851 | 2014-04-21 21:27:08 | [diff] [blame] | 344 | #endif |
[email protected] | 57b8bb35 | 2012-01-11 05:11:46 | [diff] [blame] | 345 | |
[email protected] | 365e821c | 2010-04-16 19:38:33 | [diff] [blame] | 346 | void ChromeViewsDelegate::AddRef() { |
dgn | 6dd1bb2 | 2016-04-13 19:10:04 | [diff] [blame] | 347 | if (ref_count_ == 0u) { |
| 348 | keep_alive_.reset( |
| 349 | new ScopedKeepAlive(KeepAliveOrigin::CHROME_VIEWS_DELEGATE, |
| 350 | KeepAliveRestartOption::DISABLED)); |
| 351 | } |
| 352 | |
| 353 | ++ref_count_; |
[email protected] | 365e821c | 2010-04-16 19:38:33 | [diff] [blame] | 354 | } |
| 355 | |
| 356 | void ChromeViewsDelegate::ReleaseRef() { |
dgn | 6dd1bb2 | 2016-04-13 19:10:04 | [diff] [blame] | 357 | DCHECK_NE(0u, ref_count_); |
| 358 | |
| 359 | if (--ref_count_ == 0u) |
| 360 | keep_alive_.reset(); |
[email protected] | 365e821c | 2010-04-16 19:38:33 | [diff] [blame] | 361 | } |
[email protected] | 882e27e | 2011-05-25 19:41:35 | [diff] [blame] | 362 | |
[email protected] | e7b1831 | 2013-01-04 12:17:18 | [diff] [blame] | 363 | void ChromeViewsDelegate::OnBeforeWidgetInit( |
| 364 | views::Widget::InitParams* params, |
| 365 | views::internal::NativeWidgetDelegate* delegate) { |
[email protected] | fe07d2b | 2013-12-18 10:18:38 | [diff] [blame] | 366 | // We need to determine opacity if it's not already specified. |
| 367 | if (params->opacity == views::Widget::InitParams::INFER_OPACITY) |
| 368 | params->opacity = GetOpacityForInitParams(*params); |
| 369 | |
[email protected] | e7b1831 | 2013-01-04 12:17:18 | [diff] [blame] | 370 | // If we already have a native_widget, we don't have to try to come |
| 371 | // up with one. |
| 372 | if (params->native_widget) |
| 373 | return; |
| 374 | |
sky | 7fa479a | 2016-02-10 21:09:38 | [diff] [blame] | 375 | if (!native_widget_factory().is_null()) { |
| 376 | params->native_widget = native_widget_factory().Run(*params, delegate); |
| 377 | if (params->native_widget) |
| 378 | return; |
| 379 | } |
| 380 | |
[email protected] | 0f440df | 2013-04-02 07:43:22 | [diff] [blame] | 381 | #if defined(USE_AURA) && !defined(OS_CHROMEOS) |
| 382 | bool use_non_toplevel_window = |
[email protected] | c347648 | 2014-05-27 20:12:24 | [diff] [blame] | 383 | params->parent && |
ananta | a694c74 | 2016-01-13 00:26:13 | [diff] [blame] | 384 | #if defined(OS_WIN) |
| 385 | // Check the force_software_compositing flag only on Windows. If this |
| 386 | // flag is on, it means that the widget being created wants to use the |
| 387 | // software compositor which requires a top level window. We cannot have |
| 388 | // a mixture of compositors active in one view hierarchy. |
ananta | 21d7aae2 | 2016-01-11 21:35:51 | [diff] [blame] | 389 | !params->force_software_compositing && |
ananta | a694c74 | 2016-01-13 00:26:13 | [diff] [blame] | 390 | #else |
| 391 | params->type != views::Widget::InitParams::TYPE_MENU && |
| 392 | #endif |
[email protected] | c347648 | 2014-05-27 20:12:24 | [diff] [blame] | 393 | params->type != views::Widget::InitParams::TYPE_TOOLTIP; |
[email protected] | 4d9b083 | 2013-06-14 06:25:37 | [diff] [blame] | 394 | |
| 395 | #if defined(OS_WIN) |
| 396 | // On desktop Linux Chrome must run in an environment that supports a variety |
| 397 | // of window managers, some of which do not play nicely with parts of our UI |
| 398 | // that have specific expectations about window sizing and placement. For this |
[email protected] | f7e5d90 | 2014-05-22 19:56:31 | [diff] [blame] | 399 | // reason windows opened as top level (!params.child) are always constrained |
| 400 | // by the browser frame, so we can position them correctly. This has some |
| 401 | // negative side effects, like dialogs being clipped by the browser frame, but |
| 402 | // the side effects are not as bad as the poor window manager interactions. On |
| 403 | // Windows however these WM interactions are not an issue, so we open windows |
| 404 | // requested as top_level as actual top level windows on the desktop. |
scottmg | e0c631f | 2016-02-20 06:16:29 | [diff] [blame] | 405 | use_non_toplevel_window = use_non_toplevel_window && params->child; |
[email protected] | 4d9b083 | 2013-06-14 06:25:37 | [diff] [blame] | 406 | |
[email protected] | e30ecf71 | 2013-11-01 23:21:09 | [diff] [blame] | 407 | if (!ui::win::IsAeroGlassEnabled()) { |
| 408 | // If we don't have composition (either because Glass is not enabled or |
| 409 | // because it was disabled at the command line), anything that requires |
| 410 | // transparency will be broken with a toplevel window, so force the use of |
| 411 | // a non toplevel window. |
| 412 | if (params->opacity == views::Widget::InitParams::TRANSLUCENT_WINDOW && |
ananta | 21d7aae2 | 2016-01-11 21:35:51 | [diff] [blame] | 413 | !params->force_software_compositing) |
[email protected] | e30ecf71 | 2013-11-01 23:21:09 | [diff] [blame] | 414 | use_non_toplevel_window = true; |
| 415 | } else { |
| 416 | // If we're on Vista+ with composition enabled, then we can use toplevel |
| 417 | // windows for most things (they get blended via WS_EX_COMPOSITED, which |
| 418 | // allows for animation effects, but also exceeding the bounds of the parent |
| 419 | // window). |
scottmg | d12621f | 2016-03-18 16:14:27 | [diff] [blame] | 420 | if (params->parent && |
[email protected] | e30ecf71 | 2013-11-01 23:21:09 | [diff] [blame] | 421 | params->type != views::Widget::InitParams::TYPE_CONTROL && |
| 422 | params->type != views::Widget::InitParams::TYPE_WINDOW) { |
| 423 | // When we set this to false, we get a DesktopNativeWidgetAura from the |
| 424 | // default case (not handled in this function). |
| 425 | use_non_toplevel_window = false; |
| 426 | } |
[email protected] | 0f440df | 2013-04-02 07:43:22 | [diff] [blame] | 427 | } |
| 428 | #endif // OS_WIN |
Sadrul Habib Chowdhury | cf536a3 | 2015-11-24 07:40:01 | [diff] [blame] | 429 | |
| 430 | if (!use_non_toplevel_window && !native_widget_factory().is_null()) { |
| 431 | params->native_widget = native_widget_factory().Run(*params, delegate); |
| 432 | return; |
| 433 | } |
[email protected] | 0f440df | 2013-04-02 07:43:22 | [diff] [blame] | 434 | #endif // USE_AURA |
| 435 | |
scottmg | d12621f | 2016-03-18 16:14:27 | [diff] [blame] | 436 | #if defined(OS_CHROMEOS) || defined(USE_ASH) |
[email protected] | 2a2caa0 | 2013-01-22 20:50:36 | [diff] [blame] | 437 | // When we are doing straight chromeos builds, we still need to handle the |
| 438 | // toplevel window case. |
[email protected] | 1403ada9 | 2013-02-21 00:11:47 | [diff] [blame] | 439 | // There may be a few remaining widgets in Chrome OS that are not top level, |
| 440 | // but have neither a context nor a parent. Provide a fallback context so |
| 441 | // users don't crash. Developers will hit the DCHECK and should provide a |
| 442 | // context. |
[email protected] | f8c094b8 | 2013-10-24 20:28:20 | [diff] [blame] | 443 | if (params->context) |
| 444 | params->context = params->context->GetRootWindow(); |
[email protected] | f7e5d90 | 2014-05-22 19:56:31 | [diff] [blame] | 445 | DCHECK(params->parent || params->context || !params->child) |
[email protected] | 391e6b7 | 2013-02-04 18:03:01 | [diff] [blame] | 446 | << "Please provide a parent or context for this widget."; |
| 447 | if (!params->parent && !params->context) |
[email protected] | 2a2caa0 | 2013-01-22 20:50:36 | [diff] [blame] | 448 | params->context = ash::Shell::GetPrimaryRootWindow(); |
| 449 | #elif defined(USE_AURA) |
[email protected] | e7b1831 | 2013-01-04 12:17:18 | [diff] [blame] | 450 | // While the majority of the time, context wasn't plumbed through due to the |
sky | 28f20d6 | 2016-10-20 23:21:59 | [diff] [blame] | 451 | // existence of a global WindowParentingClient, if this window is toplevel, |
| 452 | // it's possible that there is no contextual state that we can use. |
[email protected] | c347648 | 2014-05-27 20:12:24 | [diff] [blame] | 453 | if (params->parent == NULL && params->context == NULL && !params->child) { |
scottmg | d12621f | 2016-03-18 16:14:27 | [diff] [blame] | 454 | params->native_widget = new views::DesktopNativeWidgetAura(delegate); |
[email protected] | 0f440df | 2013-04-02 07:43:22 | [diff] [blame] | 455 | } else if (use_non_toplevel_window) { |
[email protected] | 98e0f096 | 2014-04-24 23:42:11 | [diff] [blame] | 456 | views::NativeWidgetAura* native_widget = |
| 457 | new views::NativeWidgetAura(delegate); |
| 458 | if (params->parent) { |
| 459 | Profile* parent_profile = reinterpret_cast<Profile*>( |
| 460 | params->parent->GetNativeWindowProperty(Profile::kProfileKey)); |
| 461 | native_widget->SetNativeWindowProperty(Profile::kProfileKey, |
| 462 | parent_profile); |
| 463 | } |
| 464 | params->native_widget = native_widget; |
[email protected] | c347648 | 2014-05-27 20:12:24 | [diff] [blame] | 465 | } else { |
scottmg | e0c631f | 2016-02-20 06:16:29 | [diff] [blame] | 466 | params->native_widget = new views::DesktopNativeWidgetAura(delegate); |
[email protected] | e7b1831 | 2013-01-04 12:17:18 | [diff] [blame] | 467 | } |
| 468 | #endif |
[email protected] | 2f0dcb6 | 2012-09-13 22:49:51 | [diff] [blame] | 469 | } |
[email protected] | 01e06a3 | 2013-06-07 12:41:33 | [diff] [blame] | 470 | |
[email protected] | 02abfee | 2014-01-23 09:27:02 | [diff] [blame] | 471 | #if defined(OS_LINUX) && !defined(OS_CHROMEOS) |
[email protected] | e9fe851 | 2014-04-21 21:27:08 | [diff] [blame] | 472 | bool ChromeViewsDelegate::WindowManagerProvidesTitleBar(bool maximized) { |
[email protected] | 02abfee | 2014-01-23 09:27:02 | [diff] [blame] | 473 | // On Ubuntu Unity, the system always provides a title bar for maximized |
| 474 | // windows. |
| 475 | views::LinuxUI* ui = views::LinuxUI::instance(); |
| 476 | return maximized && ui && ui->UnityIsRunning(); |
[email protected] | 02abfee | 2014-01-23 09:27:02 | [diff] [blame] | 477 | } |
[email protected] | e9fe851 | 2014-04-21 21:27:08 | [diff] [blame] | 478 | #endif |
[email protected] | 02abfee | 2014-01-23 09:27:02 | [diff] [blame] | 479 | |
[email protected] | 7c191384 | 2014-05-19 18:06:39 | [diff] [blame] | 480 | ui::ContextFactory* ChromeViewsDelegate::GetContextFactory() { |
| 481 | return content::GetContextFactory(); |
| 482 | } |
[email protected] | 7c191384 | 2014-05-19 18:06:39 | [diff] [blame] | 483 | |
fsamuel | a0bcfe1 | 2016-12-14 06:21:49 | [diff] [blame] | 484 | ui::ContextFactoryPrivate* ChromeViewsDelegate::GetContextFactoryPrivate() { |
| 485 | return content::GetContextFactoryPrivate(); |
| 486 | } |
| 487 | |
Dominic Mazzoni | 0e9bcce | 2015-03-16 20:51:09 | [diff] [blame] | 488 | std::string ChromeViewsDelegate::GetApplicationName() { |
sdefresne | 9fb6769 | 2015-08-03 18:48:22 | [diff] [blame] | 489 | return version_info::GetProductName(); |
Dominic Mazzoni | 0e9bcce | 2015-03-16 20:51:09 | [diff] [blame] | 490 | } |
| 491 | |
[email protected] | 6c52fef | 2014-04-22 20:26:53 | [diff] [blame] | 492 | #if defined(OS_WIN) |
| 493 | int ChromeViewsDelegate::GetAppbarAutohideEdges(HMONITOR monitor, |
| 494 | const base::Closure& callback) { |
| 495 | // Initialize the map with EDGE_BOTTOM. This is important, as if we return an |
| 496 | // initial value of 0 (no auto-hide edges) then we'll go fullscreen and |
| 497 | // windows will automatically remove WS_EX_TOPMOST from the appbar resulting |
| 498 | // in us thinking there is no auto-hide edges. By returning at least one edge |
| 499 | // we don't initially go fullscreen until we figure out the real auto-hide |
| 500 | // edges. |
| 501 | if (!appbar_autohide_edge_map_.count(monitor)) |
| 502 | appbar_autohide_edge_map_[monitor] = EDGE_BOTTOM; |
ananta | abe5bdc | 2016-12-03 03:32:47 | [diff] [blame] | 503 | |
| 504 | // We use the SHAppBarMessage API to get the taskbar autohide state. This API |
| 505 | // spins a modal loop which could cause callers to be reentered. To avoid |
| 506 | // that we retrieve the taskbar state in a worker thread. |
[email protected] | 6c52fef | 2014-04-22 20:26:53 | [diff] [blame] | 507 | if (monitor && !in_autohide_edges_callback_) { |
| 508 | base::PostTaskAndReplyWithResult( |
| 509 | content::BrowserThread::GetBlockingPool(), |
| 510 | FROM_HERE, |
| 511 | base::Bind(&GetAppbarAutohideEdgesOnWorkerThread, |
| 512 | monitor), |
| 513 | base::Bind(&ChromeViewsDelegate::OnGotAppbarAutohideEdges, |
| 514 | weak_factory_.GetWeakPtr(), |
| 515 | callback, |
| 516 | monitor, |
| 517 | appbar_autohide_edge_map_[monitor])); |
| 518 | } |
| 519 | return appbar_autohide_edge_map_[monitor]; |
| 520 | } |
| 521 | |
| 522 | void ChromeViewsDelegate::OnGotAppbarAutohideEdges( |
| 523 | const base::Closure& callback, |
| 524 | HMONITOR monitor, |
| 525 | int returned_edges, |
| 526 | int edges) { |
| 527 | appbar_autohide_edge_map_[monitor] = edges; |
| 528 | if (returned_edges == edges) |
| 529 | return; |
| 530 | |
| 531 | base::AutoReset<bool> in_callback_setter(&in_autohide_edges_callback_, true); |
| 532 | callback.Run(); |
| 533 | } |
| 534 | #endif |
| 535 | |
robliao | 57e58c2 | 2015-05-23 00:58:30 | [diff] [blame] | 536 | scoped_refptr<base::TaskRunner> |
| 537 | ChromeViewsDelegate::GetBlockingPoolTaskRunner() { |
| 538 | return content::BrowserThread::GetBlockingPool(); |
| 539 | } |
| 540 | |
ellyjones | 50ef64e | 2016-11-22 19:48:13 | [diff] [blame] | 541 | gfx::Insets ChromeViewsDelegate::GetDialogButtonInsets() { |
| 542 | if (ui::MaterialDesignController::IsSecondaryUiMaterial()) |
| 543 | return gfx::Insets(HarmonyLayoutDelegate::kHarmonyLayoutUnit); |
| 544 | return ViewsDelegate::GetDialogButtonInsets(); |
| 545 | } |
| 546 | |
| 547 | int ChromeViewsDelegate::GetDialogRelatedButtonHorizontalSpacing() { |
| 548 | if (ui::MaterialDesignController::IsSecondaryUiMaterial()) |
| 549 | return HarmonyLayoutDelegate::kHarmonyLayoutUnit / 2; |
| 550 | return ViewsDelegate::GetDialogRelatedButtonHorizontalSpacing(); |
| 551 | } |
| 552 | |
kylixrd | 44ec2a4f | 2017-01-10 21:03:16 | [diff] [blame] | 553 | int ChromeViewsDelegate::GetDialogRelatedControlVerticalSpacing() { |
| 554 | if (ui::MaterialDesignController::IsSecondaryUiMaterial()) |
| 555 | return HarmonyLayoutDelegate::kHarmonyLayoutUnit / 2; |
| 556 | return ViewsDelegate::GetDialogRelatedControlVerticalSpacing(); |
| 557 | } |
| 558 | |
ellyjones | 9bf7c586 | 2016-12-07 18:22:05 | [diff] [blame] | 559 | gfx::Insets ChromeViewsDelegate::GetDialogFrameViewInsets() { |
kylixrd | 44ec2a4f | 2017-01-10 21:03:16 | [diff] [blame] | 560 | if (ui::MaterialDesignController::IsSecondaryUiMaterial()) |
ellyjones | 9bf7c586 | 2016-12-07 18:22:05 | [diff] [blame] | 561 | // Titles are inset at the top and sides, but not at the bottom. |
| 562 | return gfx::Insets(HarmonyLayoutDelegate::kHarmonyLayoutUnit, |
| 563 | HarmonyLayoutDelegate::kHarmonyLayoutUnit, 0, |
| 564 | HarmonyLayoutDelegate::kHarmonyLayoutUnit); |
ellyjones | 9bf7c586 | 2016-12-07 18:22:05 | [diff] [blame] | 565 | return ViewsDelegate::GetDialogFrameViewInsets(); |
| 566 | } |
| 567 | |
kylixrd | 44ec2a4f | 2017-01-10 21:03:16 | [diff] [blame] | 568 | gfx::Insets ChromeViewsDelegate::GetBubbleDialogMargins() { |
| 569 | if (ui::MaterialDesignController::IsSecondaryUiMaterial()) |
| 570 | return gfx::Insets(HarmonyLayoutDelegate::kHarmonyLayoutUnit); |
| 571 | return ViewsDelegate::GetBubbleDialogMargins(); |
| 572 | } |
| 573 | |
bshe | a1838dc | 2015-11-18 22:38:35 | [diff] [blame] | 574 | #if !defined(USE_ASH) |
[email protected] | fe07d2b | 2013-12-18 10:18:38 | [diff] [blame] | 575 | views::Widget::InitParams::WindowOpacity |
| 576 | ChromeViewsDelegate::GetOpacityForInitParams( |
| 577 | const views::Widget::InitParams& params) { |
| 578 | return views::Widget::InitParams::OPAQUE_WINDOW; |
| 579 | } |
| 580 | #endif |