Add ICU message format support
[chromium-blink-merge.git] / content / browser / theme_helper_mac.mm
blobcf11744839fcee4c776c0ae49ce49c8ea30d128e
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "content/browser/theme_helper_mac.h"
7 #import <Cocoa/Cocoa.h>
9 #include "base/command_line.h"
10 #include "base/mac/mac_util.h"
11 #include "base/mac/sdk_forward_declarations.h"
12 #include "content/common/view_messages.h"
13 #include "content/public/browser/browser_thread.h"
14 #include "content/public/browser/notification_service.h"
15 #include "content/public/browser/notification_types.h"
16 #include "content/public/browser/render_process_host.h"
17 #include "content/public/common/content_switches.h"
19 namespace {
20 bool GetScrollAnimationEnabled() {
21   bool enabled = false;
22   id value = nil;
23   if (base::mac::IsOSMountainLionOrLater()) {
24     value = [[NSUserDefaults standardUserDefaults]
25         objectForKey:@"NSScrollAnimationEnabled"];
26   } else {
27     value = [[NSUserDefaults standardUserDefaults]
28         objectForKey:@"AppleScrollAnimationEnabled"];
29   }
30   if (value)
31     enabled = [value boolValue];
32   return enabled;
35 blink::ScrollbarButtonsPlacement GetButtonPlacement() {
36   NSString* scrollbar_variant = [[NSUserDefaults standardUserDefaults]
37       objectForKey:@"AppleScrollBarVariant"];
38   if ([scrollbar_variant isEqualToString:@"Single"])
39     return blink::ScrollbarButtonsPlacementSingle;
40   else if ([scrollbar_variant isEqualToString:@"DoubleMin"])
41     return blink::ScrollbarButtonsPlacementDoubleStart;
42   else if ([scrollbar_variant isEqualToString:@"DoubleBoth"])
43     return blink::ScrollbarButtonsPlacementDoubleBoth;
44   else
45     return blink::ScrollbarButtonsPlacementDoubleEnd;
47 } // namespace
49 @interface ScrollbarPrefsObserver : NSObject
51 + (void)registerAsObserver;
52 + (void)appearancePrefsChanged:(NSNotification*)notification;
53 + (void)behaviorPrefsChanged:(NSNotification*)notification;
54 + (void)notifyPrefsChangedWithRedraw:(BOOL)redraw;
56 @end
58 @implementation ScrollbarPrefsObserver
60 + (void)registerAsObserver {
61   [[NSDistributedNotificationCenter defaultCenter]
62       addObserver:self
63          selector:@selector(appearancePrefsChanged:)
64              name:@"AppleAquaScrollBarVariantChanged"
65            object:nil
66 suspensionBehavior:NSNotificationSuspensionBehaviorDeliverImmediately];
68   [[NSDistributedNotificationCenter defaultCenter]
69       addObserver:self
70          selector:@selector(behaviorPrefsChanged:)
71              name:@"AppleNoRedisplayAppearancePreferenceChanged"
72            object:nil
73 suspensionBehavior:NSNotificationSuspensionBehaviorCoalesce];
75   if (base::mac::IsOSMountainLionOrLater()) {
76     [[NSDistributedNotificationCenter defaultCenter]
77                addObserver:self
78                   selector:@selector(behaviorPrefsChanged:)
79                       name:@"NSScrollAnimationEnabled"
80                     object:nil
81         suspensionBehavior:NSNotificationSuspensionBehaviorCoalesce];
82   } else {
83     // Register for < 10.8
84     [[NSDistributedNotificationCenter defaultCenter]
85                addObserver:self
86                   selector:@selector(behaviorPrefsChanged:)
87                       name:@"AppleScrollAnimationEnabled"
88                     object:nil
89         suspensionBehavior:NSNotificationSuspensionBehaviorCoalesce];
90   }
92   [[NSDistributedNotificationCenter defaultCenter]
93              addObserver:self
94                 selector:@selector(appearancePrefsChanged:)
95                     name:@"AppleScrollBarVariant"
96                   object:nil
97       suspensionBehavior:NSNotificationSuspensionBehaviorDeliverImmediately];
99   // In single-process mode, renderers will catch these notifications
100   // themselves and listening for them here may trigger the DCHECK in Observe().
101   if ([NSScroller respondsToSelector:@selector(preferredScrollerStyle)] &&
102       !base::CommandLine::ForCurrentProcess()->HasSwitch(
103           switches::kSingleProcess)) {
104     [[NSNotificationCenter defaultCenter]
105         addObserver:self
106            selector:@selector(behaviorPrefsChanged:)
107                name:NSPreferredScrollerStyleDidChangeNotification
108              object:nil];
109   }
112 + (void)appearancePrefsChanged:(NSNotification*)notification {
113   [self notifyPrefsChangedWithRedraw:YES];
116 + (void)behaviorPrefsChanged:(NSNotification*)notification {
117   [self notifyPrefsChangedWithRedraw:NO];
120 + (void)notifyPrefsChangedWithRedraw:(BOOL)redraw {
121   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
122   NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
123   [defaults synchronize];
125   content::ThemeHelperMac::SendThemeChangeToAllRenderers(
126       [defaults floatForKey:@"NSScrollerButtonDelay"],
127       [defaults floatForKey:@"NSScrollerButtonPeriod"],
128       [defaults boolForKey:@"AppleScrollerPagingBehavior"],
129       content::ThemeHelperMac::GetPreferredScrollerStyle(), redraw,
130       GetScrollAnimationEnabled(), GetButtonPlacement());
133 @end
135 namespace content {
137 // static
138 ThemeHelperMac* ThemeHelperMac::GetInstance() {
139   return Singleton<ThemeHelperMac,
140       LeakySingletonTraits<ThemeHelperMac> >::get();
143 // static
144 blink::ScrollerStyle ThemeHelperMac::GetPreferredScrollerStyle() {
145   if (![NSScroller respondsToSelector:@selector(preferredScrollerStyle)])
146     return blink::ScrollerStyleLegacy;
147   return static_cast<blink::ScrollerStyle>([NSScroller preferredScrollerStyle]);
150 // static
151 void ThemeHelperMac::SendThemeChangeToAllRenderers(
152     float initial_button_delay,
153     float autoscroll_button_delay,
154     bool jump_on_track_click,
155     blink::ScrollerStyle preferred_scroller_style,
156     bool redraw,
157     bool scroll_animation_enabled,
158     blink::ScrollbarButtonsPlacement button_placement) {
159   ViewMsg_UpdateScrollbarTheme_Params params;
160   params.initial_button_delay = initial_button_delay;
161   params.autoscroll_button_delay = autoscroll_button_delay;
162   params.jump_on_track_click = jump_on_track_click;
163   params.preferred_scroller_style = preferred_scroller_style;
164   params.redraw = redraw;
165   params.scroll_animation_enabled = scroll_animation_enabled;
166   params.button_placement = button_placement;
168   for (RenderProcessHost::iterator it(RenderProcessHost::AllHostsIterator());
169        !it.IsAtEnd();
170        it.Advance()) {
171     it.GetCurrentValue()->Send(new ViewMsg_UpdateScrollbarTheme(params));
172   }
175 ThemeHelperMac::ThemeHelperMac() {
176   [ScrollbarPrefsObserver registerAsObserver];
177   registrar_.Add(this,
178                  NOTIFICATION_RENDERER_PROCESS_CREATED,
179                  NotificationService::AllSources());
182 ThemeHelperMac::~ThemeHelperMac() {
185 void ThemeHelperMac::Observe(int type,
186                              const NotificationSource& source,
187                              const NotificationDetails& details) {
188   DCHECK_EQ(NOTIFICATION_RENDERER_PROCESS_CREATED, type);
190   DCHECK_CURRENTLY_ON(BrowserThread::UI);
191   NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
192   [defaults synchronize];
194   RenderProcessHost* rph = Source<RenderProcessHost>(source).ptr();
196   ViewMsg_UpdateScrollbarTheme_Params params;
197   params.initial_button_delay = [defaults floatForKey:@"NSScrollerButtonDelay"];
198   params.autoscroll_button_delay =
199       [defaults floatForKey:@"NSScrollerButtonPeriod"];
200   params.jump_on_track_click =
201       [defaults boolForKey:@"AppleScrollerPagingBehavior"];
202   params.preferred_scroller_style = GetPreferredScrollerStyle();
203   params.redraw = false;
204   params.scroll_animation_enabled = GetScrollAnimationEnabled();
205   params.button_placement = GetButtonPlacement();
207   rph->Send(new ViewMsg_UpdateScrollbarTheme(params));
210 }  // namespace content