|
22 | 22 |
|
23 | 23 | #if defined(OS_WIN) |
24 | 24 | #include <shobjidl.h> |
| 25 | +#include <dwmapi.h> |
25 | 26 | #endif |
26 | 27 |
|
27 | 28 | #include "base/strings/utf_string_conversions.h" |
28 | 29 | #include "base/values.h" |
| 30 | +#include "base/command_line.h" |
29 | 31 |
|
30 | 32 | #if defined(OS_WIN) |
31 | 33 | #include "base/win/scoped_comptr.h" |
|
44 | 46 | #include "content/public/browser/render_view_host.h" |
45 | 47 | #include "content/public/browser/render_widget_host_view.h" |
46 | 48 | #include "content/public/browser/web_contents.h" |
| 49 | +#include "content/public/common/content_switches.h" |
47 | 50 | #include "extensions/common/draggable_region.h" |
48 | 51 | #include "third_party/skia/include/core/SkPaint.h" |
49 | 52 | #include "ui/base/hit_test.h" |
|
58 | 61 | #include "ui/gfx/font_list.h" |
59 | 62 | #include "ui/gfx/platform_font.h" |
60 | 63 | #include "ui/gfx/image/image_skia_operations.h" |
| 64 | +#include "ui/views/background.h" |
61 | 65 | #include "ui/views/controls/webview/webview.h" |
62 | 66 | #include "ui/views/layout/box_layout.h" |
63 | 67 | #include "ui/views/views_delegate.h" |
| 68 | +#include "ui/views/views_switches.h" |
64 | 69 | #include "ui/views/widget/widget.h" |
65 | 70 | #include "ui/views/window/native_frame_view.h" |
66 | 71 | #include "ui/views/widget/native_widget_private.h" |
@@ -291,6 +296,7 @@ NativeWindowAura::NativeWindowAura(const base::WeakPtr<content::Shell>& shell, |
291 | 296 | params.delegate = this; |
292 | 297 | params.remove_standard_frame = !has_frame(); |
293 | 298 | params.use_system_default_icon = true; |
| 299 | + if (transparent_) params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW; |
294 | 300 | if (is_fullscreen_) |
295 | 301 | params.show_state = ui::SHOW_STATE_FULLSCREEN; |
296 | 302 |
|
@@ -389,6 +395,85 @@ bool NativeWindowAura::IsFullscreen() { |
389 | 395 | return is_fullscreen_; |
390 | 396 | } |
391 | 397 |
|
| 398 | +void NativeWindowAura::SetTransparent(bool transparent) { |
| 399 | +#if defined(OS_WIN) |
| 400 | + // Check for Windows Vista or higher, transparency isn't supported in |
| 401 | + // anything lower. |
| 402 | + if (base::win::GetVersion() < base::win::VERSION_VISTA) { |
| 403 | + NOTREACHED() << "The operating system does not support transparency."; |
| 404 | + transparent_ = false; |
| 405 | + return; |
| 406 | + } |
| 407 | + |
| 408 | + // Check to see if composition is disabled, if so we have to throw an |
| 409 | + // error, there's no graceful recovery, yet. TODO: Graceful recovery. |
| 410 | + BOOL enabled = FALSE; |
| 411 | + HRESULT result = ::DwmIsCompositionEnabled(&enabled); |
| 412 | + if (!enabled || !SUCCEEDED(result)) { |
| 413 | + NOTREACHED() << "Windows DWM composition is not enabled, transparency is not supported."; |
| 414 | + transparent_ = false; |
| 415 | + return; |
| 416 | + } |
| 417 | + |
| 418 | + HWND hWnd = views::HWNDForWidget(window_); |
| 419 | + |
| 420 | + const int marginVal = transparent ? -1 : 0; |
| 421 | + MARGINS mgMarInset = { marginVal, marginVal, marginVal, marginVal }; |
| 422 | + if (DwmExtendFrameIntoClientArea(hWnd, &mgMarInset) != S_OK) { |
| 423 | + NOTREACHED() << "Windows DWM extending to client area failed, transparency is not supported."; |
| 424 | + transparent_ = false; |
| 425 | + return; |
| 426 | + } |
| 427 | + |
| 428 | + // this is needed, or transparency will fail if it defined on startup |
| 429 | + bool change_window_style = false; |
| 430 | + |
| 431 | + if (!has_frame_) { |
| 432 | + const LONG lastStyle = GetWindowLong(hWnd, GWL_STYLE); |
| 433 | + const LONG style = WS_CAPTION; |
| 434 | + const LONG newStyle = transparent ? lastStyle | style : lastStyle & ~style; |
| 435 | + SetWindowLong(hWnd, GWL_STYLE, newStyle); |
| 436 | + change_window_style |= lastStyle != newStyle; |
| 437 | + } |
| 438 | + |
| 439 | + const LONG lastExStyle = GetWindowLong(hWnd, GWL_EXSTYLE); |
| 440 | + const LONG exStyle = WS_EX_COMPOSITED; |
| 441 | + const LONG newExStyle = transparent ? lastExStyle | exStyle : lastExStyle & ~exStyle; |
| 442 | + SetWindowLong(hWnd, GWL_EXSTYLE, newExStyle); |
| 443 | + change_window_style |= lastExStyle != newExStyle; |
| 444 | + |
| 445 | + if (change_window_style) { |
| 446 | + window_->FrameTypeChanged(); |
| 447 | + } |
| 448 | +#elif defined(USE_X11) && !defined(OS_CHROMEOS) |
| 449 | + |
| 450 | + static char cachedRes = -1; |
| 451 | + if ( cachedRes<0 ) { |
| 452 | + const CommandLine& command_line = *CommandLine::ForCurrentProcess(); |
| 453 | + cachedRes = !command_line.HasSwitch(switches::kDisableGpu) || |
| 454 | + !command_line.HasSwitch(views::switches::kEnableTransparentVisuals); |
| 455 | + } |
| 456 | + |
| 457 | + if (cachedRes && transparent) { |
| 458 | + LOG(INFO) << "if transparency does not work, try with --enable-transparent-visuals --disable-gpu"; |
| 459 | + } |
| 460 | + |
| 461 | + #endif |
| 462 | + |
| 463 | + if (toolbar_) { |
| 464 | + toolbar_->set_background(transparent ? views::Background::CreateSolidBackground(SK_ColorTRANSPARENT) : |
| 465 | + views::Background::CreateStandardPanelBackground()); |
| 466 | + toolbar_->SchedulePaint(); |
| 467 | + } |
| 468 | + |
| 469 | + content::RenderWidgetHostView* rwhv = shell_->web_contents()->GetRenderWidgetHostView(); |
| 470 | + if (rwhv) { |
| 471 | + rwhv->SetBackgroundOpaque(!transparent); |
| 472 | + } |
| 473 | + |
| 474 | + transparent_ = transparent; |
| 475 | +} |
| 476 | + |
392 | 477 | void NativeWindowAura::SetSize(const gfx::Size& size) { |
393 | 478 | window_->SetSize(size); |
394 | 479 | } |
|
0 commit comments