Skip to content
This repository was archived by the owner on Sep 2, 2021. It is now read-only.

Commit ee2e509

Browse files
committed
Merge pull request #472 from adobe/jeff/PopupSizing-Final
Implement Sizing on Popup Windows
2 parents 8196d2a + 674d31c commit ee2e509

File tree

5 files changed

+176
-0
lines changed

5 files changed

+176
-0
lines changed

appshell/client_handler.cpp

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include "appshell/appshell_extensions.h"
1616
#include "appshell/command_callbacks.h"
1717

18+
1819
// Custom menu command Ids.
1920
enum client_menu_ids {
2021
CLIENT_ID_SHOW_DEVTOOLS = MENU_ID_USER_FIRST,
@@ -68,6 +69,83 @@ bool ClientHandler::OnProcessMessageReceived(
6869
return handled;
6970
}
7071

72+
#ifndef OS_LINUX
73+
74+
// CefWIndowInfo.height/.width aren't impelemented on Linux for some reason
75+
// we'll want to revisit this when we integrate the next version of CEF
76+
77+
static void SetValue(const std::string& name, const std::string& value, CefWindowInfo& windowInfo) {
78+
if (name == "height") {
79+
windowInfo.height = ::atoi(value.c_str());
80+
} else if (name == "width") {
81+
windowInfo.width = ::atoi(value.c_str());
82+
}
83+
}
84+
85+
static void ParseParams(const std::string& params, CefWindowInfo& windowInfo) {
86+
std::string name;
87+
std::string value;
88+
bool foundAssignmentToken = false;
89+
90+
for (unsigned i = 0; i < params.length(); i++) {
91+
if (params[i] == '&') {
92+
SetValue(name, value, windowInfo);
93+
name.clear();
94+
value.clear();
95+
foundAssignmentToken = false;
96+
} else if (params[i] == '=') {
97+
foundAssignmentToken = true;
98+
} else if (!foundAssignmentToken) {
99+
name += params[i];
100+
} else {
101+
value+= params[i];
102+
}
103+
}
104+
105+
// set the last parsed value that didn't end with an &
106+
SetValue(name, value, windowInfo);
107+
}
108+
109+
#endif
110+
111+
bool ClientHandler::OnBeforePopup(CefRefPtr<CefBrowser> browser,
112+
CefRefPtr<CefFrame> frame,
113+
const CefString& target_url,
114+
const CefString& target_frame_name,
115+
const CefPopupFeatures& popupFeatures,
116+
CefWindowInfo& windowInfo,
117+
CefRefPtr<CefClient>& client,
118+
CefBrowserSettings& settings,
119+
bool* no_javascript_access) {
120+
#ifndef OS_LINUX
121+
std::string address = target_url.ToString();
122+
std::string url;
123+
std::string params;
124+
bool foundParamToken = false;
125+
126+
// make the input lower-case (easier string matching)
127+
std::transform(address.begin(), address.end(), address.begin(), ::tolower);
128+
129+
for (unsigned i = 0; i < address.length(); i++) {
130+
if (!foundParamToken) {
131+
if (address[i] == L'?') {
132+
foundParamToken = true;
133+
} else {
134+
url += address[i];
135+
}
136+
} else {
137+
params += address[i];
138+
}
139+
}
140+
141+
if (url == "about:blank") {
142+
ParseParams(params, windowInfo);
143+
ComputePopupPlacement(windowInfo);
144+
}
145+
#endif
146+
return false;
147+
}
148+
71149
void ClientHandler::OnAfterCreated(CefRefPtr<CefBrowser> browser) {
72150
REQUIRE_UI_THREAD();
73151

appshell/client_handler.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@
1313
#include "util.h"
1414
#include "command_callbacks.h"
1515

16+
#include <algorithm>
17+
18+
19+
1620
// Define this value to redirect all popup URLs to the main application browser
1721
// window.
1822
// #define TEST_REDIRECT_POPUP_URLS
@@ -27,6 +31,7 @@ class ClientHandler : public CefClient,
2731
public CefKeyboardHandler,
2832
public CefGeolocationHandler,
2933
public CefContextMenuHandler {
34+
3035
public:
3136
// Interface for process message delegates. Do not perform work in the
3237
// RenderDelegate constructor.
@@ -100,6 +105,15 @@ class ClientHandler : public CefClient,
100105
}
101106

102107
// CefLifeSpanHandler methods
108+
virtual bool OnBeforePopup(CefRefPtr<CefBrowser> browser,
109+
CefRefPtr<CefFrame> frame,
110+
const CefString& target_url,
111+
const CefString& target_frame_name,
112+
const CefPopupFeatures& popupFeatures,
113+
CefWindowInfo& windowInfo,
114+
CefRefPtr<CefClient>& client,
115+
CefBrowserSettings& settings,
116+
bool* no_javascript_access) OVERRIDE;
103117
virtual void OnAfterCreated(CefRefPtr<CefBrowser> browser) OVERRIDE;
104118
virtual bool DoClose(CefRefPtr<CefBrowser> browser) OVERRIDE;
105119
virtual void OnBeforeClose(CefRefPtr<CefBrowser> browser) OVERRIDE;
@@ -216,6 +230,7 @@ class ClientHandler : public CefClient,
216230
void SetLoading(bool isLoading);
217231
void SetNavState(bool canGoBack, bool canGoForward);
218232
void PopupCreated(CefRefPtr<CefBrowser> browser);
233+
void ComputePopupPlacement(CefWindowInfo& windowInfo);
219234

220235
// Create all of ProcessMessageDelegate objects.
221236
static void CreateProcessMessageDelegates(

appshell/client_handler_gtk.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,11 @@ void ClientHandler::CloseMainWindow() {
6969
gtk_main_quit();
7070
}
7171

72+
void ClientHandler::ComputePopupPlacement(CefWindowInfo& windowInfo)
73+
{
74+
// TODO Finish this thing
75+
}
76+
7277
void ClientHandler::PopupCreated(CefRefPtr<CefBrowser> browser)
7378
{
7479
// TODO Finish this thing

appshell/client_handler_mac.mm

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -404,9 +404,46 @@ - (void)windowDidResignKey:(NSNotification *)notification {
404404
}
405405
@end
406406

407+
static bool centerMe = false;
408+
409+
void ClientHandler::ComputePopupPlacement(CefWindowInfo& windowInfo)
410+
{
411+
// CEF will transform the Y value returned here and use it to create
412+
// the window which ends up placing the window not where we want it
413+
// Just set a flag to center the window using cocoa apis in PopupCreated
414+
centerMe = true;
415+
}
416+
417+
407418
void ClientHandler::PopupCreated(CefRefPtr<CefBrowser> browser) {
408419
NSWindow* window = [browser->GetHost()->GetWindowHandle() window];
420+
409421
[window setCollectionBehavior: (1 << 7) /* NSWindowCollectionBehaviorFullScreenPrimary */];
422+
423+
424+
if (centerMe) {
425+
#ifdef _USE_COCOA_CENTERING
426+
// Center on the display
427+
[window center];
428+
#else
429+
// Center within the main window
430+
NSWindow* mainWindow = [m_MainHwnd window];
431+
NSRect rect = [mainWindow frame];
432+
NSRect windowRect = [window frame];
433+
434+
float mW = rect.size.width;
435+
float mH = rect.size.height;
436+
float cW = windowRect.size.width;
437+
float cH = windowRect.size.height;
438+
439+
windowRect.origin.x = (rect.origin.x + (mW /2)) - (cW / 2);
440+
windowRect.origin.y = (rect.origin.y + (mH /2)) - (cH / 2);
441+
442+
[window setFrame:windowRect display:YES];
443+
#endif
444+
centerMe = false;
445+
}
446+
410447

411448
// CEF3 is now using a window delegate with this revision http://code.google.com/p/chromiumembedded/source/detail?r=1149
412449
// And the declaration of the window delegate (CefWindowDelegate class) is in libcef/browser/browser_host_impl_mac.mm and
@@ -427,6 +464,7 @@ - (void)windowDidResignKey:(NSNotification *)notification {
427464
[window setDelegate:delegate];
428465
[delegate initUI];
429466
}
467+
430468
}
431469

432470
bool ClientHandler::OnPreKeyEvent(CefRefPtr<CefBrowser> browser,

appshell/client_handler_win.cpp

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@
1414

1515
#include "cef_popup_window.h"
1616

17+
#include "cef_main_window.h"
18+
extern cef_main_window* gMainWnd;
19+
20+
1721
// Additional globals
1822
extern HACCEL hAccelTable;
1923

@@ -115,3 +119,39 @@ bool ClientHandler::OnKeyEvent(CefRefPtr<CefBrowser> browser,
115119
CefEventHandle os_event) {
116120
return false;
117121
}
122+
123+
124+
void ClientHandler::ComputePopupPlacement(CefWindowInfo& windowInfo)
125+
{
126+
RECT rectMainWnd;
127+
gMainWnd->GetWindowRect(&rectMainWnd);
128+
129+
int mW = ::RectWidth(rectMainWnd);
130+
int mH = ::RectHeight(rectMainWnd);
131+
int cW = windowInfo.width;
132+
int cH = windowInfo.height;
133+
134+
windowInfo.x = (rectMainWnd.left + (mW /2)) - (cW / 2);
135+
windowInfo.y = (rectMainWnd.top + (mH /2)) - (cH / 2);
136+
137+
// don't go offscreen
138+
if (windowInfo.x < 0) windowInfo.x = 0;
139+
if (windowInfo.y < 0) windowInfo.y = 0;
140+
141+
HMONITOR hm = ::MonitorFromWindow(gMainWnd->GetSafeWnd(), MONITOR_DEFAULTTONEAREST);
142+
MONITORINFO mi = {0};
143+
mi.cbSize = sizeof (mi);
144+
145+
GetMonitorInfo(hm, &mi);
146+
147+
if (windowInfo.width > ::RectWidth(mi.rcWork)) {
148+
windowInfo.x = mi.rcWork.left;
149+
windowInfo.width = mi.rcWork.right - windowInfo.x;
150+
}
151+
152+
if (windowInfo.height > ::RectHeight(mi.rcWork)) {
153+
windowInfo.y = mi.rcWork.top;
154+
windowInfo.height = mi.rcWork.bottom - windowInfo.y;
155+
}
156+
}
157+

0 commit comments

Comments
 (0)