1 // Copyright (c) 2006-2008 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.
5 #include "chrome/browser/frame_util.h"
7 #include "base/message_loop.h"
8 #include "base/win_util.h"
9 #include "chrome/app/result_codes.h"
10 #include "chrome/browser/app_modal_dialog_queue.h"
11 #include "chrome/browser/browser.h"
12 #include "chrome/browser/browser_list.h"
13 #include "chrome/browser/browser_process.h"
14 #include "chrome/browser/browser_shutdown.h"
15 #include "chrome/browser/profile.h"
16 #include "chrome/browser/profile_manager.h"
17 #include "chrome/browser/render_view_host.h"
18 #include "chrome/browser/views/old_frames/simple_vista_frame.h"
19 #include "chrome/browser/views/old_frames/simple_xp_frame.h"
20 #include "chrome/browser/views/old_frames/vista_frame.h"
21 #include "chrome/browser/views/old_frames/xp_frame.h"
22 #include "chrome/browser/web_contents.h"
23 #include "chrome/common/notification_source.h"
24 #include "chrome/common/win_util.h"
25 #include "chrome/views/focus_manager.h"
27 // TODO(beng): clean this up
28 static const wchar_t* kBrowserWindowKey
= L
"__BROWSER_WINDOW__";
31 void FrameUtil::RegisterBrowserWindow(BrowserWindow
* frame
) {
32 DCHECK(!g_browser_process
->IsUsingNewFrames());
33 HWND h
= reinterpret_cast<HWND
>(frame
->GetPlatformID());
34 win_util::SetWindowUserData(h
, frame
);
38 BrowserWindow
* FrameUtil::GetBrowserWindowForHWND(HWND hwnd
) {
40 if (g_browser_process
->IsUsingNewFrames()) {
41 HANDLE data
= GetProp(hwnd
, kBrowserWindowKey
);
43 return reinterpret_cast<BrowserWindow
*>(data
);
45 std::wstring class_name
= win_util::GetClassName(hwnd
);
46 if (class_name
== VISTA_FRAME_CLASSNAME
||
47 class_name
== XP_FRAME_CLASSNAME
) {
48 // Need to check for both, as it's possible to have vista and xp frames
49 // at the same time (you can get into this state when connecting via
50 // remote desktop to a vista machine with Chrome already running).
51 return static_cast<BrowserWindow
*>(win_util::GetWindowUserData(hwnd
));
59 BrowserWindow
* FrameUtil::CreateBrowserWindow(const gfx::Rect
& bounds
,
61 DCHECK(!g_browser_process
->IsUsingNewFrames());
63 BrowserWindow
* frame
= NULL
;
65 switch (browser
->GetType()) {
66 case BrowserType::TABBED_BROWSER
: {
67 bool is_off_the_record
= browser
->profile()->IsOffTheRecord();
68 if (win_util::ShouldUseVistaFrame())
69 frame
= VistaFrame::CreateFrame(bounds
, browser
, is_off_the_record
);
71 frame
= XPFrame::CreateFrame(bounds
, browser
, is_off_the_record
);
74 case BrowserType::APPLICATION
:
75 case BrowserType::BROWSER
:
76 if (win_util::ShouldUseVistaFrame())
77 frame
= SimpleVistaFrame::CreateFrame(bounds
, browser
);
79 frame
= SimpleXPFrame::CreateFrame(bounds
, browser
);
82 NOTREACHED() << "Browser type unknown or not yet implemented";
90 bool FrameUtil::LoadAccelerators(BrowserWindow
* frame
,
91 HACCEL accelerator_table
,
92 ChromeViews::AcceleratorTarget
* accelerator_target
) {
93 DCHECK(!g_browser_process
->IsUsingNewFrames());
95 // We have to copy the table to access its contents.
96 int count
= CopyAcceleratorTable(accelerator_table
, 0, 0);
98 // Nothing to do in that case.
102 ACCEL
* accelerators
= static_cast<ACCEL
*>(malloc(sizeof(ACCEL
) * count
));
103 CopyAcceleratorTable(accelerator_table
, accelerators
, count
);
105 HWND hwnd
= static_cast<HWND
>(frame
->GetPlatformID());
106 ChromeViews::FocusManager
* focus_manager
=
107 ChromeViews::FocusManager::GetFocusManager(hwnd
);
108 DCHECK(focus_manager
);
110 // Let's build our own accelerator table.
111 std::map
<ChromeViews::Accelerator
, int>* our_accelerators
=
112 new std::map
<ChromeViews::Accelerator
, int>;
113 for (int i
= 0; i
< count
; ++i
) {
114 bool alt_down
= (accelerators
[i
].fVirt
& FALT
) == FALT
;
115 bool ctrl_down
= (accelerators
[i
].fVirt
& FCONTROL
) == FCONTROL
;
116 bool shift_down
= (accelerators
[i
].fVirt
& FSHIFT
) == FSHIFT
;
117 ChromeViews::Accelerator
accelerator(accelerators
[i
].key
,
118 shift_down
, ctrl_down
, alt_down
);
119 (*our_accelerators
)[accelerator
] = accelerators
[i
].cmd
;
121 // Also register with the focus manager.
122 focus_manager
->RegisterAccelerator(accelerator
, accelerator_target
);
125 // We don't need the Windows accelerator table anymore.
128 // Now set the accelerator table on the frame who becomes the owner.
129 frame
->SetAcceleratorTable(our_accelerators
);
135 bool FrameUtil::ActivateAppModalDialog(Browser
* browser
) {
136 DCHECK(!g_browser_process
->IsUsingNewFrames());
138 // If another browser is app modal, flash and activate the modal browser.
139 if (BrowserList::IsShowingAppModalDialog()) {
140 if (browser
!= BrowserList::GetLastActive()) {
141 BrowserList::GetLastActive()->window()->FlashFrame();
142 BrowserList::GetLastActive()->MoveToFront(true);
144 AppModalDialogQueue::ActivateModalDialog();
151 // TODO(beng): post new frames, move somewhere more logical, maybe Browser or
153 void FrameUtil::EndSession() {
154 // EndSession is invoked once per frame. Only do something the first time.
155 static bool already_ended
= false;
158 already_ended
= true;
160 browser_shutdown::OnShutdownStarting(browser_shutdown::END_SESSION
);
162 // Write important data first.
163 g_browser_process
->EndSession();
165 // Close all the browsers.
166 BrowserList::CloseAllBrowsers(false);
168 // Send out notification. This is used during testing so that the test harness
169 // can properly shutdown before we exit.
170 NotificationService::current()->Notify(NOTIFY_SESSION_END
,
171 NotificationService::AllSources(),
172 NotificationService::NoDetails());
175 browser_shutdown::Shutdown();
177 // At this point the message loop is still running yet we've shut everything
178 // down. If any messages are processed we'll likely crash. Exit now.
179 ExitProcess(ResultCodes::NORMAL_EXIT
);