|
22 | 22 |
|
23 | 23 | #include "base/utf_string_conversions.h"
|
24 | 24 | #include "base/values.h"
|
| 25 | +#include "base/logging.h" |
25 | 26 | #include "base/win/wrapped_window_proc.h"
|
26 | 27 | #include "chrome/browser/platform_util.h"
|
27 | 28 | #include "chrome/common/extensions/draggable_region.h"
|
@@ -317,7 +318,79 @@ bool NativeWindowWin::IsFullscreen() {
|
317 | 318 | return is_fullscreen_;
|
318 | 319 | }
|
319 | 320 |
|
| 321 | +void NativeWindowWin::UpdateWindowAttribute(int attribute_index, |
| 322 | + int attribute_value_to_set, |
| 323 | + int attribute_value_to_reset, |
| 324 | + bool update_frame) { |
| 325 | + HWND native_window = window_->GetNativeWindow(); |
| 326 | + int value = ::GetWindowLong(native_window, attribute_index); |
| 327 | + int expected_value = value; |
| 328 | + if (attribute_value_to_set) |
| 329 | + expected_value |= attribute_value_to_set; |
| 330 | + if (attribute_value_to_reset) |
| 331 | + expected_value &= ~attribute_value_to_reset; |
| 332 | + if (value != expected_value) |
| 333 | + ::SetWindowLong(native_window, attribute_index, expected_value); |
| 334 | + |
| 335 | + // Per MSDN, if any of the frame styles is changed, SetWindowPos with the |
| 336 | + // SWP_FRAMECHANGED flag must be called in order for the cached window data |
| 337 | + // to be updated properly. |
| 338 | + // http://msdn.microsoft.com/en-us/library/windows/desktop/ms633591(v=vs.85).aspx |
| 339 | + if (update_frame) { |
| 340 | + ::SetWindowPos(native_window, NULL, 0, 0, 0, 0, |
| 341 | + SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOSIZE | |
| 342 | + SWP_NOZORDER | SWP_NOACTIVATE); |
| 343 | + } |
| 344 | +} |
| 345 | + |
320 | 346 | void NativeWindowWin::SetSize(const gfx::Size& size) {
|
| 347 | + |
| 348 | + |
| 349 | + if (!this->has_frame()) { |
| 350 | + // An overlapped window is a top-level window that has a titlebar, border, |
| 351 | + // and client area. The Windows system will automatically put the shadow |
| 352 | + // around the whole window. Also the system will enforce the minimum height |
| 353 | + // (38 pixels based on observation) for the overlapped window such that it |
| 354 | + // will always has the space for the titlebar. |
| 355 | + // |
| 356 | + // On contrast, a popup window is a bare minimum window without border and |
| 357 | + // titlebar by default. It is often used for the popup menu and the window |
| 358 | + // with short life. The Windows system does not add the shadow around the |
| 359 | + // whole window though CS_DROPSHADOW class style could be passed to add the |
| 360 | + // drop shadow which is only around the right and bottom edges. |
| 361 | + // |
| 362 | + // The height of the title-only or minimized panel is smaller than the minimum |
| 363 | + // overlapped window height. If the panel still uses the overlapped window |
| 364 | + // style, Windows system will automatically increase the window height. To |
| 365 | + // work around this limitation, we temporarily change the window style to |
| 366 | + // popup when the height to set is smaller than the minimum overlapped window |
| 367 | + // height and then restore the window style to overlapped when the height |
| 368 | + // grows. |
| 369 | + |
| 370 | + static const int kMinimumOverlappedWindowHeight = 38; |
| 371 | + gfx::Rect old_bounds = GetWidget()->GetRestoredBounds(); |
| 372 | + gfx::Rect new_bounds(size); |
| 373 | + if (old_bounds.height() > kMinimumOverlappedWindowHeight && |
| 374 | + new_bounds.height() <= kMinimumOverlappedWindowHeight) { |
| 375 | + // When the panel height shrinks below the minimum overlapped window height, |
| 376 | + // change the window style to popup such that we can show the title-only |
| 377 | + // and minimized panel without additional height being added by the system. |
| 378 | + UpdateWindowAttribute(GWL_STYLE, |
| 379 | + WS_POPUP, |
| 380 | + WS_OVERLAPPED | WS_THICKFRAME | WS_SYSMENU, |
| 381 | + true); |
| 382 | + } else if (old_bounds.height() <= kMinimumOverlappedWindowHeight && |
| 383 | + new_bounds.height() > kMinimumOverlappedWindowHeight) { |
| 384 | + // Change the window style back to overlappped when the panel height grow |
| 385 | + // taller than the minimum overlapped window height. |
| 386 | + UpdateWindowAttribute(GWL_STYLE, |
| 387 | + WS_OVERLAPPED | WS_THICKFRAME | WS_SYSMENU, |
| 388 | + WS_POPUP, |
| 389 | + true); |
| 390 | + } |
| 391 | + |
| 392 | + } |
| 393 | + |
321 | 394 | window_->SetSize(size);
|
322 | 395 | }
|
323 | 396 |
|
|
0 commit comments