diff options
-rw-r--r-- | chrome/app/generated_resources.grd | 6 | ||||
-rw-r--r-- | chrome/browser/accessibility/invert_bubble_views.cc | 135 | ||||
-rw-r--r-- | chrome/browser/accessibility/invert_bubble_views.h | 27 | ||||
-rw-r--r-- | chrome/browser/prefs/browser_prefs.cc | 2 | ||||
-rw-r--r-- | chrome/browser/ui/views/frame/browser_view.cc | 12 | ||||
-rw-r--r-- | chrome/browser/ui/views/frame/browser_view.h | 11 | ||||
-rw-r--r-- | chrome/browser/ui/webui/ntp/ntp_resource_cache.cc | 39 | ||||
-rw-r--r-- | chrome/chrome_browser.gypi | 2 | ||||
-rw-r--r-- | chrome/common/pref_names.cc | 4 | ||||
-rw-r--r-- | chrome/common/pref_names.h | 2 | ||||
-rw-r--r-- | content/browser/accessibility/browser_accessibility_state_impl.cc | 4 | ||||
-rw-r--r-- | content/browser/renderer_host/render_view_host_impl.cc | 8 | ||||
-rw-r--r-- | content/browser/renderer_host/render_widget_host_view_win.cc | 9 | ||||
-rw-r--r-- | content/browser/renderer_host/render_widget_host_view_win.h | 9 | ||||
-rw-r--r-- | ui/gfx/color_utils.cc | 8 | ||||
-rw-r--r-- | ui/gfx/color_utils.h | 6 | ||||
-rw-r--r-- | ui/gfx/sys_color_change_listener.cc | 118 | ||||
-rw-r--r-- | ui/gfx/sys_color_change_listener.h | 45 | ||||
-rw-r--r-- | ui/ui.gyp | 2 |
19 files changed, 426 insertions, 23 deletions
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd index 85c726a..c643945 100644 --- a/chrome/app/generated_resources.grd +++ b/chrome/app/generated_resources.grd @@ -15419,6 +15419,12 @@ Battery full </message> </if> + <!-- Inverting for high-constrast mode. --> + <message name="IDS_INVERT_NOTIFICATION" + desc="Text that explains that Chrome has inverted (i.e. reversed black and white) all web pages because the user is using Windows High-Constrast mode with an inverted color scheme."> + Web pages are displayed inverted because you have High Constrast mode enabled and you're using a light-on-dark color scheme. + </message> + </messages> <structures fallback_to_english="true"> <!-- Make sure these stay in sync with the structures in generated_resources.grd. --> diff --git a/chrome/browser/accessibility/invert_bubble_views.cc b/chrome/browser/accessibility/invert_bubble_views.cc new file mode 100644 index 0000000..d6971b1 --- /dev/null +++ b/chrome/browser/accessibility/invert_bubble_views.cc @@ -0,0 +1,135 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/utf_string_conversions.h" +#include "chrome/browser/accessibility/invert_bubble_views.h" +#include "chrome/browser/prefs/pref_service.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/browser/ui/browser_list.h" +#include "chrome/browser/ui/views/event_utils.h" +#include "chrome/browser/ui/views/window.h" +#include "chrome/common/pref_names.h" +#include "content/public/browser/page_navigator.h" +#include "grit/generated_resources.h" +#include "ui/base/l10n/l10n_util.h" +#include "ui/base/resource/resource_bundle.h" +#include "ui/gfx/sys_color_change_listener.h" +#include "ui/views/bubble/bubble_delegate.h" +#include "ui/views/controls/button/button.h" +#include "ui/views/controls/label.h" +#include "ui/views/controls/link.h" +#include "ui/views/controls/link_listener.h" +#include "ui/views/layout/grid_layout.h" +#include "ui/views/layout/layout_constants.h" + +namespace { +const char kLearnMoreUrl[] = "https://groups.google.com/a/googleproductforums.com/d/topic/chrome/Xrco2HsXS-8/discussion"; +const int kBubbleWidth = 500; +} // namespace + +class InvertBubbleView : public views::BubbleDelegateView, + public views::LinkListener { + public: + InvertBubbleView(Profile* profile, views::View* anchor_view); + virtual ~InvertBubbleView(); + + // views::BubbleDelegateView overrides: + virtual gfx::Rect GetAnchorRect() OVERRIDE; + + protected: + // views::BubbleDelegateView overrides: + virtual void Init() OVERRIDE; + + // views::LinkListener overrides: + virtual void LinkClicked(views::Link* source, int event_flags) OVERRIDE; + + Profile* profile_; + + DISALLOW_COPY_AND_ASSIGN(InvertBubbleView); +}; + +void InvertBubbleView::Init() { + ResourceBundle& rb = ResourceBundle::GetSharedInstance(); + const gfx::Font& original_font = rb.GetFont(ResourceBundle::MediumFont); + + views::Label* title = new views::Label( + l10n_util::GetStringUTF16(IDS_INVERT_NOTIFICATION)); + title->SetFont(original_font.DeriveFont(2, gfx::Font::BOLD)); + title->SetMultiLine(true); + title->SizeToFit(kBubbleWidth); + + views::Link* learn_more = + new views::Link(l10n_util::GetStringUTF16(IDS_LEARN_MORE)); + learn_more->SetFont(original_font); + learn_more->set_listener(this); + + views::GridLayout* layout = views::GridLayout::CreatePanel(this); + SetLayoutManager(layout); + + views::ColumnSet* columns = layout->AddColumnSet(0); + columns->AddColumn(views::GridLayout::LEADING, views::GridLayout::LEADING, 0, + views::GridLayout::USE_PREF, 0, 0); + + layout->StartRow(0, 0); + layout->AddView(title); + layout->StartRowWithPadding(0, 0, 0, + views::kRelatedControlSmallVerticalSpacing); + layout->AddView(learn_more); + + // Switching to high-contrast mode has a nasty habit of causing Chrome + // top-level windows to lose focus, so closing the bubble on deactivate + // makes it disappear before the user has even seen it. This forces the + // user to close it explicitly, which should be okay because it affects + // a small minority of users, and only once. + set_close_on_deactivate(false); +} + +gfx::Rect InvertBubbleView::GetAnchorRect() { + // Set the height to 0 so we display the bubble at the top of the + // anchor rect. + gfx::Rect rect(BubbleDelegateView::GetAnchorRect()); + rect.set_height(0); + return rect; +} + +InvertBubbleView::InvertBubbleView(Profile* profile, views::View* anchor_view) + : views::BubbleDelegateView(anchor_view, views::BubbleBorder::TOP_LEFT), + profile_(profile) { +} + +InvertBubbleView::~InvertBubbleView() { +} + +void InvertBubbleView::LinkClicked(views::Link* source, int event_flags) { + Browser* browser = BrowserList::GetLastActiveWithProfile(profile_); + if (browser) { + WindowOpenDisposition disposition = + event_utils::DispositionFromEventFlags(event_flags); + content::OpenURLParams params( + GURL(kLearnMoreUrl), content::Referrer(), + disposition == CURRENT_TAB ? NEW_FOREGROUND_TAB : disposition, + content::PAGE_TRANSITION_LINK, false); + browser->OpenURL(params); + } + GetWidget()->Close(); +} + +// static +void InvertBubble::RegisterUserPrefs(PrefService* prefs) { + prefs->RegisterBooleanPref(prefs::kInvertNotificationShown, + false, + PrefService::UNSYNCABLE_PREF); +} + +void InvertBubble::MaybeShowInvertBubble(Profile* profile, + views::View* anchor_view) { + PrefService* pref_service = profile->GetPrefs(); + if (gfx::IsInvertedColorScheme() && + !pref_service->GetBoolean(prefs::kInvertNotificationShown)) { + pref_service->SetBoolean(prefs::kInvertNotificationShown, true); + InvertBubbleView* delegate = new InvertBubbleView(profile, anchor_view); + browser::CreateViewsBubble(delegate); + delegate->StartFade(true); + } +} diff --git a/chrome/browser/accessibility/invert_bubble_views.h b/chrome/browser/accessibility/invert_bubble_views.h new file mode 100644 index 0000000..d38740c --- /dev/null +++ b/chrome/browser/accessibility/invert_bubble_views.h @@ -0,0 +1,27 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_ACCESSIBILITY_INVERT_BUBBLE_VIEWS_H_ +#define CHROME_BROWSER_ACCESSIBILITY_INVERT_BUBBLE_VIEWS_H_ +#pragma once + +class PrefService; +class Profile; +namespace views { +class View; +} + +class InvertBubble { + public: + static void RegisterUserPrefs(PrefService* prefs); + + // Show a bubble telling the user that web contents are inverted because + // they're using Windows high-constrast mode and their color scheme is + // light-on-dark. Only shows the first time we encounter this condition + // for a particular profile. + static void MaybeShowInvertBubble(Profile* profile, + views::View* anchor_view); +}; + +#endif // CHROME_BROWSER_ACCESSIBILITY_INVERT_BUBBLE_VIEWS_H_ diff --git a/chrome/browser/prefs/browser_prefs.cc b/chrome/browser/prefs/browser_prefs.cc index c696741..aed1810 100644 --- a/chrome/browser/prefs/browser_prefs.cc +++ b/chrome/browser/prefs/browser_prefs.cc @@ -74,6 +74,7 @@ #endif #if defined(TOOLKIT_VIEWS) // TODO(port): whittle this down as we port +#include "chrome/browser/accessibility/invert_bubble_views.h" #include "chrome/browser/ui/views/browser_actions_container.h" #include "chrome/browser/ui/views/frame/browser_view.h" #endif @@ -212,6 +213,7 @@ void RegisterUserPrefs(PrefService* user_prefs) { #if defined(TOOLKIT_VIEWS) BrowserActionsContainer::RegisterUserPrefs(user_prefs); + InvertBubble::RegisterUserPrefs(user_prefs); #elif defined(TOOLKIT_GTK) BrowserWindowGtk::RegisterUserPrefs(user_prefs); #endif diff --git a/chrome/browser/ui/views/frame/browser_view.cc b/chrome/browser/ui/views/frame/browser_view.cc index aae215b..b31942f 100644 --- a/chrome/browser/ui/views/frame/browser_view.cc +++ b/chrome/browser/ui/views/frame/browser_view.cc @@ -18,6 +18,7 @@ #include "base/utf_string_conversions.h" #include "chrome/app/chrome_command_ids.h" #include "chrome/app/chrome_dll_resource.h" +#include "chrome/browser/accessibility/invert_bubble_views.h" #include "chrome/browser/autocomplete/autocomplete_popup_model.h" #include "chrome/browser/autocomplete/autocomplete_popup_view.h" #include "chrome/browser/bookmarks/bookmark_utils.h" @@ -92,6 +93,8 @@ #include "ui/base/l10n/l10n_util.h" #include "ui/base/resource/resource_bundle.h" #include "ui/gfx/canvas.h" +#include "ui/gfx/color_utils.h" +#include "ui/gfx/sys_color_change_listener.h" #include "ui/ui_controls/ui_controls.h" #include "ui/views/controls/single_split_view.h" #include "ui/views/events/event.h" @@ -325,7 +328,8 @@ BrowserView::BrowserView(Browser* browser) ticker_(0), #endif force_location_bar_focus_(false), - move_observer_(NULL) { + move_observer_(NULL), + ALLOW_THIS_IN_INITIALIZER_LIST(color_change_listener_(this)) { browser_->tabstrip_model()->AddObserver(this); } @@ -615,6 +619,8 @@ void BrowserView::Show() { force_location_bar_focus_ = false; browser()->OnWindowDidShow(); + + InvertBubble::MaybeShowInvertBubble(browser_->profile(), contents_); } void BrowserView::ShowInactive() { @@ -1852,6 +1858,10 @@ bool BrowserView::SplitHandleMoved(views::SingleSplitView* sender) { return false; } +void BrowserView::OnSysColorChange() { + InvertBubble::MaybeShowInvertBubble(browser_->profile(), contents_); +} + views::LayoutManager* BrowserView::CreateLayoutManager() const { return new BrowserViewLayout; } diff --git a/chrome/browser/ui/views/frame/browser_view.h b/chrome/browser/ui/views/frame/browser_view.h index e0ddddd..5c592a4 100644 --- a/chrome/browser/ui/views/frame/browser_view.h +++ b/chrome/browser/ui/views/frame/browser_view.h @@ -22,6 +22,7 @@ #include "chrome/browser/ui/views/tabs/abstract_tab_strip_view.h" #include "chrome/browser/ui/views/unhandled_keyboard_event_handler.h" #include "ui/base/models/simple_menu_model.h" +#include "ui/gfx/sys_color_change_listener.h" #include "ui/gfx/native_widget_types.h" #include "ui/views/controls/single_split_view_listener.h" #include "ui/views/widget/widget_delegate.h" @@ -87,7 +88,8 @@ class BrowserView : public BrowserWindow, public views::Widget::Observer, public views::ClientView, public InfoBarContainer::Delegate, - public views::SingleSplitViewListener { + public views::SingleSplitViewListener, + public gfx::SysColorChangeListener { public: // The browser view's class name. static const char kViewClassName[]; @@ -202,7 +204,7 @@ class BrowserView : public BrowserWindow, return browser_->is_type_tabbed(); } - // Register preferences specific to this view. + // Register local state preferences specific to this view. static void RegisterBrowserViewPrefs(PrefService* prefs); // Returns true if the specified point(BrowserView coordinates) is in @@ -404,6 +406,9 @@ class BrowserView : public BrowserWindow, // views::SingleSplitViewListener overrides: virtual bool SplitHandleMoved(views::SingleSplitView* sender) OVERRIDE; + // gfx::ScopedSysColorChangeListener overrides: + virtual void OnSysColorChange() OVERRIDE; + protected: // Appends to |toolbars| a pointer to each AccessiblePaneView that // can be traversed using F6, in the order they should be traversed. @@ -718,6 +723,8 @@ class BrowserView : public BrowserWindow, BrowserWindowMoveObserver* move_observer_; + gfx::ScopedSysColorChangeListener color_change_listener_; + DISALLOW_COPY_AND_ASSIGN(BrowserView); }; diff --git a/chrome/browser/ui/webui/ntp/ntp_resource_cache.cc b/chrome/browser/ui/webui/ntp/ntp_resource_cache.cc index a037cb0..b18bf16 100644 --- a/chrome/browser/ui/webui/ntp/ntp_resource_cache.cc +++ b/chrome/browser/ui/webui/ntp/ntp_resource_cache.cc @@ -49,6 +49,7 @@ #include "ui/base/resource/resource_bundle.h" #include "ui/base/theme_provider.h" #include "ui/gfx/color_utils.h" +#include "ui/gfx/sys_color_change_listener.h" #if defined(OS_WIN) || defined(TOOLKIT_VIEWS) #include "chrome/browser/ui/views/bookmarks/bookmark_bar_view.h" @@ -108,6 +109,14 @@ std::string SkColorToRGBComponents(SkColor color) { SkColorGetB(color)); } +SkColor GetThemeColor(ui::ThemeProvider* tp, int id) { + SkColor color = tp->GetColor(id); + // If web contents are being inverted because the system is in high-contrast + // mode, any system theme colors we use must be inverted too to cancel out. + return gfx::IsInvertedColorScheme() ? + color_utils::InvertColor(color) : color; +} + // Get the CSS string for the background position on the new tab page for the // states when the bar is attached or detached. std::string GetNewTabBackgroundCSS(const ui::ThemeProvider* theme_provider, @@ -420,7 +429,7 @@ void NTPResourceCache::CreateNewTabIncognitoCSS() { // Get our theme colors SkColor color_background = - tp->GetColor(ThemeService::COLOR_NTP_BACKGROUND); + GetThemeColor(tp, ThemeService::COLOR_NTP_BACKGROUND); // Generate the replacements. std::vector<std::string> subst; @@ -453,33 +462,33 @@ void NTPResourceCache::CreateNewTabCSS() { // Get our theme colors SkColor color_background = - tp->GetColor(ThemeService::COLOR_NTP_BACKGROUND); - SkColor color_text = tp->GetColor(ThemeService::COLOR_NTP_TEXT); - SkColor color_link = tp->GetColor(ThemeService::COLOR_NTP_LINK); + GetThemeColor(tp, ThemeService::COLOR_NTP_BACKGROUND); + SkColor color_text = GetThemeColor(tp, ThemeService::COLOR_NTP_TEXT); + SkColor color_link = GetThemeColor(tp, ThemeService::COLOR_NTP_LINK); SkColor color_link_underline = - tp->GetColor(ThemeService::COLOR_NTP_LINK_UNDERLINE); + GetThemeColor(tp, ThemeService::COLOR_NTP_LINK_UNDERLINE); SkColor color_section = - tp->GetColor(ThemeService::COLOR_NTP_SECTION); + GetThemeColor(tp, ThemeService::COLOR_NTP_SECTION); SkColor color_section_text = - tp->GetColor(ThemeService::COLOR_NTP_SECTION_TEXT); + GetThemeColor(tp, ThemeService::COLOR_NTP_SECTION_TEXT); SkColor color_section_link = - tp->GetColor(ThemeService::COLOR_NTP_SECTION_LINK); + GetThemeColor(tp, ThemeService::COLOR_NTP_SECTION_LINK); SkColor color_section_link_underline = - tp->GetColor(ThemeService::COLOR_NTP_SECTION_LINK_UNDERLINE); + GetThemeColor(tp, ThemeService::COLOR_NTP_SECTION_LINK_UNDERLINE); SkColor color_section_header_text = - tp->GetColor(ThemeService::COLOR_NTP_SECTION_HEADER_TEXT); + GetThemeColor(tp, ThemeService::COLOR_NTP_SECTION_HEADER_TEXT); SkColor color_section_header_text_hover = - tp->GetColor(ThemeService::COLOR_NTP_SECTION_HEADER_TEXT_HOVER); + GetThemeColor(tp, ThemeService::COLOR_NTP_SECTION_HEADER_TEXT_HOVER); SkColor color_section_header_rule = - tp->GetColor(ThemeService::COLOR_NTP_SECTION_HEADER_RULE); + GetThemeColor(tp, ThemeService::COLOR_NTP_SECTION_HEADER_RULE); SkColor color_section_header_rule_light = - tp->GetColor(ThemeService::COLOR_NTP_SECTION_HEADER_RULE_LIGHT); + GetThemeColor(tp, ThemeService::COLOR_NTP_SECTION_HEADER_RULE_LIGHT); SkColor color_text_light = - tp->GetColor(ThemeService::COLOR_NTP_TEXT_LIGHT); + GetThemeColor(tp, ThemeService::COLOR_NTP_TEXT_LIGHT); SkColor color_header = - tp->GetColor(ThemeService::COLOR_NTP_HEADER); + GetThemeColor(tp, ThemeService::COLOR_NTP_HEADER); // Generate a lighter color for the header gradients. color_utils::HSL header_lighter; color_utils::SkColorToHSL(color_header, &header_lighter); diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index dcd2da9..5b84718 100644 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi @@ -90,6 +90,8 @@ 'browser/accessibility/accessibility_extension_api_constants.h', 'browser/accessibility/accessibility_events.cc', 'browser/accessibility/accessibility_events.h', + 'browser/accessibility/invert_bubble_views.cc', + 'browser/accessibility/invert_bubble_views.h', 'browser/aeropeek_manager.cc', 'browser/aeropeek_manager.h', 'browser/alternate_nav_url_fetcher.cc', diff --git a/chrome/common/pref_names.cc b/chrome/common/pref_names.cc index 211ddcd..6b72aed8 100644 --- a/chrome/common/pref_names.cc +++ b/chrome/common/pref_names.cc @@ -942,6 +942,10 @@ const char kPasswordsUseLocalProfileId[] = const char kProfileAvatarIndex[] = "profile.avatar_index"; const char kProfileName[] = "profile.name"; +// Indicates if we've already shown a notification that web contents are +// inverted because high-contrast mode is on. +const char kInvertNotificationShown[] = "invert_notification_shown"; + // *************** LOCAL STATE *************** // These are attached to the machine/installation diff --git a/chrome/common/pref_names.h b/chrome/common/pref_names.h index afb38d3..dc9fca8 100644 --- a/chrome/common/pref_names.h +++ b/chrome/common/pref_names.h @@ -341,6 +341,8 @@ extern const char kPasswordsUseLocalProfileId[]; extern const char kProfileAvatarIndex[]; extern const char kProfileName[]; +extern const char kInvertNotificationShown[]; + // Local state prefs. Please add Profile prefs above instead. extern const char kCertRevocationCheckingEnabled[]; extern const char kSSL3Enabled[]; diff --git a/content/browser/accessibility/browser_accessibility_state_impl.cc b/content/browser/accessibility/browser_accessibility_state_impl.cc index 08c0775..7edc3e0 100644 --- a/content/browser/accessibility/browser_accessibility_state_impl.cc +++ b/content/browser/accessibility/browser_accessibility_state_impl.cc @@ -7,6 +7,7 @@ #include "base/memory/singleton.h" #include "base/metrics/histogram.h" #include "base/timer.h" +#include "ui/gfx/sys_color_change_listener.h" // Update the accessibility histogram 45 seconds after initialization. static const int kAccessibilityHistogramDelaySecs = 45; @@ -51,4 +52,7 @@ void BrowserAccessibilityStateImpl::UpdateHistogram() { UMA_HISTOGRAM_ENUMERATION("Accessibility.State", accessibility_enabled_ ? 1 : 0, 2); + UMA_HISTOGRAM_ENUMERATION("Accessibility.InvertedColors", + gfx::IsInvertedColorScheme() ? 1 : 0, + 2); } diff --git a/content/browser/renderer_host/render_view_host_impl.cc b/content/browser/renderer_host/render_view_host_impl.cc index b2e76fc..3edbcc9 100644 --- a/content/browser/renderer_host/render_view_host_impl.cc +++ b/content/browser/renderer_host/render_view_host_impl.cc @@ -58,6 +58,7 @@ #include "third_party/WebKit/Source/WebKit/chromium/public/win/WebScreenInfoFactory.h" #endif #include "ui/gfx/native_widget_types.h" +#include "ui/gfx/sys_color_change_listener.h" #include "webkit/fileapi/isolated_context.h" #include "webkit/glue/webaccessibility.h" #include "webkit/glue/webdropdata.h" @@ -250,8 +251,11 @@ bool RenderViewHostImpl::CreateRenderView(const string16& frame_name, // Let our delegate know that we created a RenderView. delegate_->RenderViewCreated(this); - // Invert the color scheme if a flag was set. - if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kInvertWebContent)) + // Invert the color scheme if the operating system's color scheme is + // inverted or if a flag is set. + if (gfx::IsInvertedColorScheme() || + CommandLine::ForCurrentProcess()->HasSwitch( + switches::kInvertWebContent)) Send(new ViewMsg_InvertWebContent(GetRoutingID(), true)); FOR_EACH_OBSERVER( diff --git a/content/browser/renderer_host/render_widget_host_view_win.cc b/content/browser/renderer_host/render_widget_host_view_win.cc index 7b45563..6cb801a 100644 --- a/content/browser/renderer_host/render_widget_host_view_win.cc +++ b/content/browser/renderer_host/render_widget_host_view_win.cc @@ -331,7 +331,8 @@ RenderWidgetHostViewWin::RenderWidgetHostViewWin(RenderWidgetHost* widget) pointer_down_context_(false), focus_on_editable_field_(false), received_focus_change_after_pointer_down_(false), - touch_events_enabled_(false) { + touch_events_enabled_(false), + ALLOW_THIS_IN_INITIALIZER_LIST(sys_color_change_listener_(this)) { render_widget_host_->SetView(this); registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_TERMINATED, @@ -1331,6 +1332,12 @@ void RenderWidgetHostViewWin::OnThemeChanged() { render_widget_host_->GetRoutingID())); } +void RenderWidgetHostViewWin::OnSysColorChange() { + render_widget_host_->Send(new ViewMsg_InvertWebContent( + render_widget_host_->GetRoutingID(), + gfx::IsInvertedColorScheme())); +} + LRESULT RenderWidgetHostViewWin::OnNotify(int w_param, NMHDR* header) { if (tooltip_hwnd_ == NULL) return 0; diff --git a/content/browser/renderer_host/render_widget_host_view_win.h b/content/browser/renderer_host/render_widget_host_view_win.h index 4dc81b4..2269430 100644 --- a/content/browser/renderer_host/render_widget_host_view_win.h +++ b/content/browser/renderer_host/render_widget_host_view_win.h @@ -28,6 +28,7 @@ #include "ui/gfx/native_widget_types.h" #include "ui/gfx/point.h" #include "ui/gfx/surface/accelerated_surface_win.h" +#include "ui/gfx/sys_color_change_listener.h" #include "webkit/glue/webcursor.h" class BackingStore; @@ -91,7 +92,8 @@ class RenderWidgetHostViewWin RenderWidgetHostHWNDTraits>, public content::RenderWidgetHostViewBase, public content::NotificationObserver, - public BrowserAccessibilityDelegate { + public BrowserAccessibilityDelegate, + public gfx::SysColorChangeListener { public: virtual ~RenderWidgetHostViewWin(); @@ -239,6 +241,9 @@ class RenderWidgetHostViewWin virtual void AccessibilitySetTextSelection( int acc_obj_id, int start_offset, int end_offset) OVERRIDE; + // Implementation of SysColorChangeListener: + virtual void OnSysColorChange() OVERRIDE; + protected: friend class content::RenderWidgetHostView; @@ -566,6 +571,8 @@ class RenderWidgetHostViewWin // Are touch events currently enabled? bool touch_events_enabled_; + gfx::ScopedSysColorChangeListener sys_color_change_listener_; + DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostViewWin); }; diff --git a/ui/gfx/color_utils.cc b/ui/gfx/color_utils.cc index a79947c..0012b24 100644 --- a/ui/gfx/color_utils.cc +++ b/ui/gfx/color_utils.cc @@ -296,6 +296,14 @@ SkColor GetReadableColor(SkColor foreground, SkColor background) { foreground : foreground2; } +SkColor InvertColor(SkColor color) { + return SkColorSetARGB( + SkColorGetA(color), + 255 - SkColorGetR(color), + 255 - SkColorGetG(color), + 255 - SkColorGetB(color)); +} + SkColor GetSysSkColor(int which) { #if defined(OS_WIN) return skia::COLORREFToSkColor(GetSysColor(which)); diff --git a/ui/gfx/color_utils.h b/ui/gfx/color_utils.h index 8f2697b..0627d34 100644 --- a/ui/gfx/color_utils.h +++ b/ui/gfx/color_utils.h @@ -6,6 +6,7 @@ #define UI_GFX_COLOR_UTILS_H_ #pragma once +#include "base/basictypes.h" #include "third_party/skia/include/core/SkColor.h" #include "ui/base/ui_export.h" @@ -20,7 +21,7 @@ struct HSL { double l; }; -unsigned char GetLuminanceForColor(SkColor color); +UI_EXPORT unsigned char GetLuminanceForColor(SkColor color); // Calculated according to http://www.w3.org/TR/WCAG20/#relativeluminancedef UI_EXPORT double RelativeLuminance(SkColor color); @@ -76,6 +77,9 @@ UI_EXPORT SkColor AlphaBlend(SkColor foreground, SkColor background, // has a luma value close to the midpoint (0.5 in the HSL representation). UI_EXPORT SkColor GetReadableColor(SkColor foreground, SkColor background); +// Invert a color. +UI_EXPORT SkColor InvertColor(SkColor color); + // Gets a Windows system color as a SkColor UI_EXPORT SkColor GetSysSkColor(int which); diff --git a/ui/gfx/sys_color_change_listener.cc b/ui/gfx/sys_color_change_listener.cc new file mode 100644 index 0000000..b6e321c --- /dev/null +++ b/ui/gfx/sys_color_change_listener.cc @@ -0,0 +1,118 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ui/gfx/color_utils.h" +#include "ui/gfx/sys_color_change_listener.h" + +#if defined(OS_WIN) +#include <windows.h> +#endif + +#include "base/basictypes.h" +#include "base/memory/singleton.h" +#include "base/observer_list.h" +#if defined(OS_WIN) +#include "ui/base/win/singleton_hwnd.h" +#endif + +namespace gfx { + +namespace { + +bool g_is_inverted_color_scheme = false; +bool g_is_inverted_color_scheme_initialized = false; + +void UpdateInvertedColorScheme() { +#if defined(OS_WIN) + int foreground = color_utils::GetLuminanceForColor( + color_utils::GetSysSkColor(COLOR_WINDOWTEXT)); + int background = color_utils::GetLuminanceForColor( + color_utils::GetSysSkColor(COLOR_WINDOW)); + HIGHCONTRAST high_contrast = {0}; + high_contrast.cbSize = sizeof(HIGHCONTRAST); + g_is_inverted_color_scheme = + SystemParametersInfo(SPI_GETHIGHCONTRAST, 0, &high_contrast, 0) && + ((high_contrast.dwFlags & HCF_HIGHCONTRASTON) != 0); + g_is_inverted_color_scheme_initialized = true; +#endif +} + +} // namespace + +bool IsInvertedColorScheme() { + if (!g_is_inverted_color_scheme_initialized) + UpdateInvertedColorScheme(); + return g_is_inverted_color_scheme; +} + +#if defined(OS_WIN) +class SysColorChangeObserver : public ui::SingletonHwnd::Observer { + public: + static SysColorChangeObserver* GetInstance(); + + void AddListener(SysColorChangeListener* listener); + void RemoveListener(SysColorChangeListener* listener); + + private: + friend struct DefaultSingletonTraits<SysColorChangeObserver>; + + SysColorChangeObserver(); + virtual ~SysColorChangeObserver(); + + virtual void OnWndProc(HWND hwnd, + UINT message, + WPARAM wparam, + LPARAM lparam) OVERRIDE; + + ObserverList<SysColorChangeListener> listeners_; +}; + +// static +SysColorChangeObserver* SysColorChangeObserver::GetInstance() { + return Singleton<SysColorChangeObserver>::get(); +} + +SysColorChangeObserver::SysColorChangeObserver() { + ui::SingletonHwnd::GetInstance()->AddObserver(this); +} + +SysColorChangeObserver::~SysColorChangeObserver() { + ui::SingletonHwnd::GetInstance()->RemoveObserver(this); +} + +void SysColorChangeObserver::AddListener(SysColorChangeListener* listener) { + listeners_.AddObserver(listener); +} + +void SysColorChangeObserver::RemoveListener(SysColorChangeListener* listener) { + listeners_.RemoveObserver(listener); +} + +void SysColorChangeObserver::OnWndProc(HWND hwnd, + UINT message, + WPARAM wparam, + LPARAM lparam) { + if (message == WM_SYSCOLORCHANGE || + (message == WM_SETTINGCHANGE && wparam == SPI_SETHIGHCONTRAST)) { + UpdateInvertedColorScheme(); + FOR_EACH_OBSERVER(SysColorChangeListener, listeners_, OnSysColorChange()); + } +} +#endif + +ScopedSysColorChangeListener::ScopedSysColorChangeListener( + SysColorChangeListener* listener) + : listener_(listener) { +#if defined(OS_WIN) + SysColorChangeObserver::GetInstance()->AddListener(listener_); +#endif +} + +ScopedSysColorChangeListener::~ScopedSysColorChangeListener() { +#if defined(OS_WIN) + SysColorChangeObserver::GetInstance()->RemoveListener(listener_); +#endif +} + +} // namespace gfx diff --git a/ui/gfx/sys_color_change_listener.h b/ui/gfx/sys_color_change_listener.h new file mode 100644 index 0000000..6cb126c --- /dev/null +++ b/ui/gfx/sys_color_change_listener.h @@ -0,0 +1,45 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef UI_GFX_SYS_COLOR_CHANGE_LISTENER_H_ +#define UI_GFX_SYS_COLOR_SCHEME_LISTENER_H_ +#pragma once + +#include "base/basictypes.h" +#include "third_party/skia/include/core/SkColor.h" +#include "ui/base/ui_export.h" + +namespace gfx { + +// Returns true only if Chrome should use an inverted color scheme - which is +// only true if the system has high-contrast mode enabled and and is using a +// light-on-dark color scheme. To be notified when this status changes, use +// ScopedSysColorChangeListener, below. +UI_EXPORT bool IsInvertedColorScheme(); + +// Interface for classes that want to listen to system color changes. +class SysColorChangeListener { + public: + virtual void OnSysColorChange() = 0; + + protected: + virtual ~SysColorChangeListener() {} +}; + +// Create an instance of this class in any object that wants to listen +// for system color changes. +class UI_EXPORT ScopedSysColorChangeListener { + public: + explicit ScopedSysColorChangeListener(SysColorChangeListener* listener); + ~ScopedSysColorChangeListener(); + + private: + SysColorChangeListener* listener_; + + DISALLOW_COPY_AND_ASSIGN(ScopedSysColorChangeListener); +}; + +} // namespace gfx; + +#endif // UI_GFX_SYS_COLOR_CHANGE_LISTENER_ @@ -358,6 +358,8 @@ 'gfx/skia_util.h', 'gfx/skia_utils_gtk.cc', 'gfx/skia_utils_gtk.h', + 'gfx/sys_color_change_listener.cc', + 'gfx/sys_color_change_listener.h', 'gfx/transform.cc', 'gfx/transform.h', 'gfx/transform_util.cc', |