@@ -99,6 +99,60 @@ LPCWSTR cef_main_window::GetBracketsWindowTitleText()
9999 return szTitle;
100100}
101101
102+ void cef_main_window::EnsureWindowRectVisibility (int & left, int & top, int & width, int & height, int showCmd)
103+ {
104+ static const int kWindowFrameSize = 8 ;
105+
106+ // don't check if we're already letting
107+ // Windows determine the window placement
108+ if (left == CW_USEDEFAULT &&
109+ top == CW_USEDEFAULT &&
110+ width == CW_USEDEFAULT &&
111+ height == CW_USEDEFAULT) {
112+ return ;
113+ }
114+
115+ // The virtual display is the bounding rect of all monitors
116+ // see http://msdn.microsoft.com/en-us/library/dd162729(v=vs.85).aspx
117+
118+ int xScreen = ::GetSystemMetrics (SM_XVIRTUALSCREEN);
119+ int yScreen = ::GetSystemMetrics (SM_YVIRTUALSCREEN);
120+ int cxScreen = ::GetSystemMetrics (SM_CXVIRTUALSCREEN);
121+ int cyScreen = ::GetSystemMetrics (SM_CYVIRTUALSCREEN);
122+
123+ // make a copy, we need to adjust the comparison
124+ // if it's a maximized window because the OS move the
125+ // origin of the window by 8 pixes to releive the borders
126+ // from the monitor for legacy apps
127+ int xLeft = left;
128+ int xTop = top;
129+ int xWidth = width;
130+ int xHeight = height;
131+
132+ if (showCmd == SW_MAXIMIZE) {
133+ xLeft += kWindowFrameSize ;
134+ xTop += kWindowFrameSize ;
135+ xWidth -= kWindowFrameSize * 2 ;
136+ xHeight -= kWindowFrameSize * 2 ;
137+ }
138+
139+ // Make sure the window fits inside the virtual screen.
140+ // If it doesn't then we let windows decide the window placement
141+ if (xLeft < xScreen ||
142+ xTop < yScreen ||
143+ xLeft + xWidth > xScreen + cxScreen ||
144+ xTop + xHeight > yScreen + cyScreen) {
145+
146+ // something was off-screen so reposition
147+ // to the default window placement
148+ left = CW_USEDEFAULT;
149+ top = CW_USEDEFAULT;
150+ width = CW_USEDEFAULT;
151+ height = CW_USEDEFAULT;
152+ }
153+ }
154+
155+
102156// Create Method. Call this to create a cef_main_window instance
103157BOOL cef_main_window::Create ()
104158{
@@ -108,10 +162,14 @@ BOOL cef_main_window::Create()
108162 int top = CW_USEDEFAULT;
109163 int width = CW_USEDEFAULT;
110164 int height = CW_USEDEFAULT;
165+
111166 int showCmd = SW_SHOW;
112167
113168 LoadWindowRestoreRect (left, top, width, height, showCmd);
114169
170+ // make sure the window is visible
171+ EnsureWindowRectVisibility (left, top, width, height, showCmd);
172+
115173 DWORD styles = WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_EX_COMPOSITED;
116174
117175 if (showCmd == SW_MAXIMIZE)
@@ -353,8 +411,32 @@ void cef_main_window::RestoreWindowPlacement(int showCmd)
353411 GetRegistryInt (::kWindowPostionFolder , ::kPrefRestoreRight , NULL , (int &)wp.rcNormalPosition .right );
354412 GetRegistryInt (::kWindowPostionFolder , ::kPrefRestoreBottom , NULL , (int &)wp.rcNormalPosition .bottom );
355413
356- // This returns FALSE on failure but not sure what we could do in that case
357- SetWindowPlacement (&wp);
414+ ::NormalizeRect (wp.rcNormalPosition);
415+
416+ int left = wp.rcNormalPosition .left ;
417+ int top = wp.rcNormalPosition .top ;
418+ int width = wp.rcNormalPosition .right - left;
419+ int height = wp.rcNormalPosition .bottom - top;
420+
421+ EnsureWindowRectVisibility (left, top, width, height, SW_SHOWNORMAL);
422+
423+ // presumably they would all be set to CW_USEDEFAULT
424+ // but we check for any out-of-bounds value and
425+ // bypass the restore rect as to let Windows decide
426+ if (left != CW_USEDEFAULT &&
427+ top != CW_USEDEFAULT &&
428+ height != CW_USEDEFAULT &&
429+ width != CW_USEDEFAULT) {
430+
431+ wp.rcNormalPosition .left = left;
432+ wp.rcNormalPosition .top = top;
433+
434+ wp.rcNormalPosition .right = wp.rcNormalPosition .left + width;
435+ wp.rcNormalPosition .bottom = wp.rcNormalPosition .top + height;
436+
437+ // This returns FALSE on failure but not sure what we could do in that case
438+ SetWindowPlacement (&wp);
439+ }
358440 }
359441
360442 ShowWindow (showCmd);
0 commit comments