Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(390)

Side by Side Diff: chrome/browser/mac/dock.mm

Issue 42153002: Merge 230360 "[mac] Support adding the launcher to the Dock when..." (Closed) Base URL: svn://svn.chromium.org/chrome/branches/1650/src/
Patch Set: Created 7 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « chrome/browser/mac/dock.h ('k') | chrome/browser/web_applications/web_app_mac.mm » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #import "chrome/browser/mac/dock.h" 5 #import "chrome/browser/mac/dock.h"
6 6
7 #include <ApplicationServices/ApplicationServices.h> 7 #include <ApplicationServices/ApplicationServices.h>
8 #import <Foundation/Foundation.h> 8 #import <Foundation/Foundation.h>
9 #include <CoreFoundation/CoreFoundation.h> 9 #include <CoreFoundation/CoreFoundation.h>
10 #include <signal.h> 10 #include <signal.h>
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
91 } 91 }
92 92
93 NSDictionary* tile_data = [app objectForKey:kDockTileDataKey]; 93 NSDictionary* tile_data = [app objectForKey:kDockTileDataKey];
94 if (![tile_data isKindOfClass:[NSDictionary class]]) { 94 if (![tile_data isKindOfClass:[NSDictionary class]]) {
95 LOG(ERROR) << "tile_data not NSDictionary"; 95 LOG(ERROR) << "tile_data not NSDictionary";
96 return nil; 96 return nil;
97 } 97 }
98 98
99 NSDictionary* file_data = [tile_data objectForKey:kDockFileDataKey]; 99 NSDictionary* file_data = [tile_data objectForKey:kDockFileDataKey];
100 if (![file_data isKindOfClass:[NSDictionary class]]) { 100 if (![file_data isKindOfClass:[NSDictionary class]]) {
101 LOG(ERROR) << "file_data not NSDictionary"; 101 // Some apps (e.g. Dashboard) have no file data, but instead have a
102 return nil; 102 // special value for the tile-type key. For these, add an empty string to
103 // align indexes with the source array.
104 [app_paths addObject:@""];
105 continue;
103 } 106 }
104 107
105 NSURL* url = NSURLCreateFromDictionary(file_data); 108 NSURL* url = NSURLCreateFromDictionary(file_data);
106 if (!url) { 109 if (!url) {
107 LOG(ERROR) << "no URL"; 110 LOG(ERROR) << "no URL";
108 return nil; 111 return nil;
109 } 112 }
110 113
111 if (![url isFileURL]) { 114 if (![url isFileURL]) {
112 LOG(ERROR) << "non-file URL"; 115 LOG(ERROR) << "non-file URL";
(...skipping 20 matching lines...) Expand all
133 // Sending a SIGHUP to the Dock seems to be a more reliable way to get the 136 // Sending a SIGHUP to the Dock seems to be a more reliable way to get the
134 // replacement Dock process to read the newly written plist than using the 137 // replacement Dock process to read the newly written plist than using the
135 // equivalent of "launchctl stop" (even if followed by "launchctl start.") 138 // equivalent of "launchctl stop" (even if followed by "launchctl start.")
136 // Note that this is a potential race in that pid may no longer be valid or 139 // Note that this is a potential race in that pid may no longer be valid or
137 // may even have been reused. 140 // may even have been reused.
138 kill(pid, SIGHUP); 141 kill(pid, SIGHUP);
139 } 142 }
140 143
141 } // namespace 144 } // namespace
142 145
143 void AddIcon(NSString* installed_path, NSString* dmg_app_path) { 146 AddIconStatus AddIcon(NSString* installed_path, NSString* dmg_app_path) {
144 // ApplicationServices.framework/Frameworks/HIServices.framework contains an 147 // ApplicationServices.framework/Frameworks/HIServices.framework contains an
145 // undocumented function, CoreDockAddFileToDock, that is able to add items 148 // undocumented function, CoreDockAddFileToDock, that is able to add items
146 // to the Dock "live" without requiring a Dock restart. Under the hood, it 149 // to the Dock "live" without requiring a Dock restart. Under the hood, it
147 // communicates with the Dock via Mach IPC. It is available as of Mac OS X 150 // communicates with the Dock via Mach IPC. It is available as of Mac OS X
148 // 10.6. AddIcon could call CoreDockAddFileToDock if available, but 151 // 10.6. AddIcon could call CoreDockAddFileToDock if available, but
149 // CoreDockAddFileToDock seems to always to add the new Dock icon last, 152 // CoreDockAddFileToDock seems to always to add the new Dock icon last,
150 // where AddIcon takes care to position the icon appropriately. Based on 153 // where AddIcon takes care to position the icon appropriately. Based on
151 // disassembly, the signature of the undocumented function appears to be 154 // disassembly, the signature of the undocumented function appears to be
152 // extern "C" OSStatus CoreDockAddFileToDock(CFURLRef url, int); 155 // extern "C" OSStatus CoreDockAddFileToDock(CFURLRef url, int);
153 // The int argument doesn't appear to have any effect. It's not used as the 156 // The int argument doesn't appear to have any effect. It's not used as the
154 // position to place the icon as hoped. 157 // position to place the icon as hoped.
155 158
156 // There's enough potential allocation in this function to justify a 159 // There's enough potential allocation in this function to justify a
157 // distinct pool. 160 // distinct pool.
158 base::mac::ScopedNSAutoreleasePool autorelease_pool; 161 base::mac::ScopedNSAutoreleasePool autorelease_pool;
159 162
160 NSString* const kDockDomain = @"com.apple.dock"; 163 NSString* const kDockDomain = @"com.apple.dock";
161 NSUserDefaults* user_defaults = [NSUserDefaults standardUserDefaults]; 164 NSUserDefaults* user_defaults = [NSUserDefaults standardUserDefaults];
162 165
163 NSDictionary* dock_plist_const = 166 NSDictionary* dock_plist_const =
164 [user_defaults persistentDomainForName:kDockDomain]; 167 [user_defaults persistentDomainForName:kDockDomain];
165 if (![dock_plist_const isKindOfClass:[NSDictionary class]]) { 168 if (![dock_plist_const isKindOfClass:[NSDictionary class]]) {
166 LOG(ERROR) << "dock_plist_const not NSDictionary"; 169 LOG(ERROR) << "dock_plist_const not NSDictionary";
167 return; 170 return IconAddFailure;
168 } 171 }
169 NSMutableDictionary* dock_plist = 172 NSMutableDictionary* dock_plist =
170 [NSMutableDictionary dictionaryWithDictionary:dock_plist_const]; 173 [NSMutableDictionary dictionaryWithDictionary:dock_plist_const];
171 174
172 NSString* const kDockPersistentAppsKey = @"persistent-apps"; 175 NSString* const kDockPersistentAppsKey = @"persistent-apps";
173 NSArray* persistent_apps_const = 176 NSArray* persistent_apps_const =
174 [dock_plist objectForKey:kDockPersistentAppsKey]; 177 [dock_plist objectForKey:kDockPersistentAppsKey];
175 if (![persistent_apps_const isKindOfClass:[NSArray class]]) { 178 if (![persistent_apps_const isKindOfClass:[NSArray class]]) {
176 LOG(ERROR) << "persistent_apps_const not NSArray"; 179 LOG(ERROR) << "persistent_apps_const not NSArray";
177 return; 180 return IconAddFailure;
178 } 181 }
179 NSMutableArray* persistent_apps = 182 NSMutableArray* persistent_apps =
180 [NSMutableArray arrayWithArray:persistent_apps_const]; 183 [NSMutableArray arrayWithArray:persistent_apps_const];
181 184
182 NSMutableArray* persistent_app_paths = PersistentAppPaths(persistent_apps); 185 NSMutableArray* persistent_app_paths = PersistentAppPaths(persistent_apps);
183 if (!persistent_app_paths) { 186 if (!persistent_app_paths) {
184 return; 187 return IconAddFailure;
185 } 188 }
186 189
187 NSUInteger already_installed_app_index = NSNotFound; 190 NSUInteger already_installed_app_index = NSNotFound;
188 NSUInteger app_index = NSNotFound; 191 NSUInteger app_index = NSNotFound;
189 for (NSUInteger index = 0; index < [persistent_apps count]; ++index) { 192 for (NSUInteger index = 0; index < [persistent_apps count]; ++index) {
190 NSString* app_path = [persistent_app_paths objectAtIndex:index]; 193 NSString* app_path = [persistent_app_paths objectAtIndex:index];
191 if ([app_path isEqualToString:installed_path]) { 194 if ([app_path isEqualToString:installed_path]) {
192 // If the Dock already contains a reference to the newly installed 195 // If the Dock already contains a reference to the newly installed
193 // application, don't add another one. 196 // application, don't add another one.
194 already_installed_app_index = index; 197 already_installed_app_index = index;
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
293 if (app_index == NSNotFound) { 296 if (app_index == NSNotFound) {
294 // Put the new application last in the Dock. 297 // Put the new application last in the Dock.
295 app_index = [persistent_apps count]; 298 app_index = [persistent_apps count];
296 } 299 }
297 300
298 // Set up the new Dock tile. 301 // Set up the new Dock tile.
299 NSURL* url = [NSURL fileURLWithPath:installed_path isDirectory:YES]; 302 NSURL* url = [NSURL fileURLWithPath:installed_path isDirectory:YES];
300 NSDictionary* url_dict = NSURLCopyDictionary(url); 303 NSDictionary* url_dict = NSURLCopyDictionary(url);
301 if (!url_dict) { 304 if (!url_dict) {
302 LOG(ERROR) << "couldn't create url_dict"; 305 LOG(ERROR) << "couldn't create url_dict";
303 return; 306 return IconAddFailure;
304 } 307 }
305 308
306 NSDictionary* new_tile_data = 309 NSDictionary* new_tile_data =
307 [NSDictionary dictionaryWithObject:url_dict 310 [NSDictionary dictionaryWithObject:url_dict
308 forKey:kDockFileDataKey]; 311 forKey:kDockFileDataKey];
309 NSDictionary* new_tile = 312 NSDictionary* new_tile =
310 [NSDictionary dictionaryWithObject:new_tile_data 313 [NSDictionary dictionaryWithObject:new_tile_data
311 forKey:kDockTileDataKey]; 314 forKey:kDockTileDataKey];
312 315
313 // Add the new tile to the Dock. 316 // Add the new tile to the Dock.
314 [persistent_apps insertObject:new_tile atIndex:app_index]; 317 [persistent_apps insertObject:new_tile atIndex:app_index];
315 [persistent_app_paths insertObject:installed_path atIndex:app_index]; 318 [persistent_app_paths insertObject:installed_path atIndex:app_index];
316 made_change = true; 319 made_change = true;
317 } 320 }
318 321
319 // Verify that the arrays are still parallel. 322 // Verify that the arrays are still parallel.
320 DCHECK_EQ([persistent_apps count], [persistent_app_paths count]); 323 DCHECK_EQ([persistent_apps count], [persistent_app_paths count]);
321 324
322 if (!made_change) { 325 if (!made_change) {
323 // If no changes were made, there's no point in rewriting the Dock's 326 // If no changes were made, there's no point in rewriting the Dock's
324 // plist or restarting the Dock. 327 // plist or restarting the Dock.
325 return; 328 return IconAlreadyPresent;
326 } 329 }
327 330
328 // Rewrite the plist. 331 // Rewrite the plist.
329 [dock_plist setObject:persistent_apps forKey:kDockPersistentAppsKey]; 332 [dock_plist setObject:persistent_apps forKey:kDockPersistentAppsKey];
330 [user_defaults setPersistentDomain:dock_plist forName:kDockDomain]; 333 [user_defaults setPersistentDomain:dock_plist forName:kDockDomain];
331 334
332 Restart(); 335 Restart();
336 return IconAddSuccess;
333 } 337 }
334 338
335 } // namespace dock 339 } // namespace dock
OLDNEW
« no previous file with comments | « chrome/browser/mac/dock.h ('k') | chrome/browser/web_applications/web_app_mac.mm » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698