1 /* -*- Mode: c++; tab-width: 2; indent-tabs-mode: nil; -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #import <Cocoa/Cocoa.h>
8 #include "nsComponentManagerUtils.h"
9 #include "nsMacDockSupport.h"
10 #include "nsObjCExceptions.h"
12 NS_IMPL_ISUPPORTS(nsMacDockSupport, nsIMacDockSupport, nsITaskbarProgress)
14 nsMacDockSupport::nsMacDockSupport()
16 , mProgressBackground(nil)
17 , mProgressState(STATE_NO_PROGRESS)
18 , mProgressFraction(0.0)
20 mProgressTimer = do_CreateInstance(NS_TIMER_CONTRACTID);
23 nsMacDockSupport::~nsMacDockSupport()
29 if (mProgressBackground) {
30 [mProgressBackground release];
31 mProgressBackground = nil;
34 mProgressTimer->Cancel();
35 mProgressTimer = nullptr;
40 nsMacDockSupport::GetDockMenu(nsIStandaloneNativeMenu ** aDockMenu)
45 return mDockMenu->QueryInterface(NS_GET_IID(nsIStandaloneNativeMenu),
46 reinterpret_cast<void **>(aDockMenu));
51 nsMacDockSupport::SetDockMenu(nsIStandaloneNativeMenu * aDockMenu)
54 mDockMenu = do_QueryInterface(aDockMenu, &rv);
59 nsMacDockSupport::ActivateApplication(bool aIgnoreOtherApplications)
61 NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
63 [[NSApplication sharedApplication] activateIgnoringOtherApps:aIgnoreOtherApplications];
66 NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
70 nsMacDockSupport::SetBadgeText(const nsAString& aBadgeText)
72 NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
74 NSDockTile *tile = [[NSApplication sharedApplication] dockTile];
75 mBadgeText = aBadgeText;
76 if (aBadgeText.IsEmpty())
77 [tile setBadgeLabel: nil];
79 [tile setBadgeLabel:[NSString stringWithCharacters:reinterpret_cast<const unichar*>(mBadgeText.get())
80 length:mBadgeText.Length()]];
83 NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
87 nsMacDockSupport::GetBadgeText(nsAString& aBadgeText)
89 aBadgeText = mBadgeText;
94 nsMacDockSupport::SetProgressState(nsTaskbarProgressState aState,
95 uint64_t aCurrentValue,
98 NS_ENSURE_ARG_RANGE(aState, 0, STATE_PAUSED);
99 if (aState == STATE_NO_PROGRESS || aState == STATE_INDETERMINATE) {
100 NS_ENSURE_TRUE(aCurrentValue == 0, NS_ERROR_INVALID_ARG);
101 NS_ENSURE_TRUE(aMaxValue == 0, NS_ERROR_INVALID_ARG);
103 if (aCurrentValue > aMaxValue) {
104 return NS_ERROR_ILLEGAL_VALUE;
107 mProgressState = aState;
108 if (aMaxValue == 0) {
109 mProgressFraction = 0;
111 mProgressFraction = (double)aCurrentValue / aMaxValue;
114 if (mProgressState == STATE_NORMAL || mProgressState == STATE_INDETERMINATE) {
115 int perSecond = 8; // Empirically determined, see bug 848792
116 mProgressTimer->InitWithFuncCallback(RedrawIconCallback, this, 1000 / perSecond,
117 nsITimer::TYPE_REPEATING_SLACK);
120 mProgressTimer->Cancel();
126 void nsMacDockSupport::RedrawIconCallback(nsITimer* aTimer, void* aClosure)
128 static_cast<nsMacDockSupport*>(aClosure)->RedrawIcon();
131 // Return whether to draw progress
132 bool nsMacDockSupport::InitProgress()
134 if (mProgressState != STATE_NORMAL && mProgressState != STATE_INDETERMINATE) {
139 mProgressTimer = do_CreateInstance(NS_TIMER_CONTRACTID);
140 mAppIcon = [[NSImage imageNamed:@"NSApplicationIcon"] retain];
141 mProgressBackground = [mAppIcon copyWithZone:nil];
142 mTheme = new nsNativeThemeCocoa();
144 NSSize sz = [mProgressBackground size];
145 mProgressBounds = CGRectMake(sz.width * 1/32, sz.height * 3/32,
146 sz.width * 30/32, sz.height * 4/32);
147 [mProgressBackground lockFocus];
148 [[NSColor whiteColor] set];
149 NSRectFill(NSRectFromCGRect(mProgressBounds));
150 [mProgressBackground unlockFocus];
156 nsMacDockSupport::RedrawIcon()
158 NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
160 if (InitProgress()) {
161 // TODO: - Implement ERROR and PAUSED states?
162 NSImage *icon = [mProgressBackground copyWithZone:nil];
163 bool isIndeterminate = (mProgressState != STATE_NORMAL);
166 CGContextRef ctx = (CGContextRef)[[NSGraphicsContext currentContext] graphicsPort];
167 mTheme->DrawProgress(ctx, mProgressBounds, isIndeterminate,
168 true, mProgressFraction, 1.0, NULL);
170 [NSApp setApplicationIconImage:icon];
173 [NSApp setApplicationIconImage:mAppIcon];
177 NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;