Skip to content

Commit a78fff0

Browse files
committed
Allow the choice of Safari menu item in order to handle Safari Profiles.
1 parent 181749c commit a78fff0

7 files changed

Lines changed: 98 additions & 37 deletions

File tree

PrivateWindow.xcodeproj/project.pbxproj

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,10 @@
3434
524A21DF2B1406CD00C30991 /* JJMainMenu.m in Sources */ = {isa = PBXBuildFile; fileRef = 524A21D12B1406CD00C30991 /* JJMainMenu.m */; };
3535
524A21E02B1406CD00C30991 /* JJLicenseWindow.m in Sources */ = {isa = PBXBuildFile; fileRef = 524A21D22B1406CD00C30991 /* JJLicenseWindow.m */; };
3636
524A21E22B1406CD00C30991 /* LICENSE.txt in Resources */ = {isa = PBXBuildFile; fileRef = 524A21D42B1406CD00C30991 /* LICENSE.txt */; };
37+
526E3C1F2B24204D009CCD86 /* FileProfiles@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 526E3C1D2B24204C009CCD86 /* FileProfiles@2x.png */; };
38+
526E3C202B24204D009CCD86 /* FileProfiles@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 526E3C1D2B24204C009CCD86 /* FileProfiles@2x.png */; };
39+
526E3C212B24204D009CCD86 /* FileDefault@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 526E3C1E2B24204D009CCD86 /* FileDefault@2x.png */; };
40+
526E3C222B24204D009CCD86 /* FileDefault@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 526E3C1E2B24204D009CCD86 /* FileDefault@2x.png */; };
3741
/* End PBXBuildFile section */
3842

3943
/* Begin PBXContainerItemProxy section */
@@ -72,6 +76,8 @@
7276
524A21D62B1406CD00C30991 /* Release.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Release.xcconfig; sourceTree = "<group>"; };
7377
524A21D82B1406CD00C30991 /* Codesign.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; path = Codesign.entitlements; sourceTree = "<group>"; };
7478
524A21D92B1406CD00C30991 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
79+
526E3C1D2B24204C009CCD86 /* FileProfiles@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "FileProfiles@2x.png"; sourceTree = "<group>"; };
80+
526E3C1E2B24204D009CCD86 /* FileDefault@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "FileDefault@2x.png"; sourceTree = "<group>"; };
7581
/* End PBXFileReference section */
7682

7783
/* Begin PBXFrameworksBuildPhase section */
@@ -134,6 +140,8 @@
134140
524A21D72B1406CD00C30991 /* nonsource */ = {
135141
isa = PBXGroup;
136142
children = (
143+
526E3C1E2B24204D009CCD86 /* FileDefault@2x.png */,
144+
526E3C1D2B24204C009CCD86 /* FileProfiles@2x.png */,
137145
524A21D92B1406CD00C30991 /* Info.plist */,
138146
524A21D82B1406CD00C30991 /* Codesign.entitlements */,
139147
);
@@ -223,6 +231,8 @@
223231
buildActionMask = 2147483647;
224232
files = (
225233
52352A2B2B1451F400442B5B /* LICENSE.txt in Resources */,
234+
526E3C202B24204D009CCD86 /* FileProfiles@2x.png in Resources */,
235+
526E3C222B24204D009CCD86 /* FileDefault@2x.png in Resources */,
226236
);
227237
runOnlyForDeploymentPostprocessing = 0;
228238
};
@@ -231,6 +241,8 @@
231241
buildActionMask = 2147483647;
232242
files = (
233243
524A21E22B1406CD00C30991 /* LICENSE.txt in Resources */,
244+
526E3C1F2B24204D009CCD86 /* FileProfiles@2x.png in Resources */,
245+
526E3C212B24204D009CCD86 /* FileDefault@2x.png in Resources */,
234246
);
235247
runOnlyForDeploymentPostprocessing = 0;
236248
};

nonsource/FileDefault@2x.png

31.1 KB
Loading

nonsource/FileProfiles@2x.png

36.8 KB
Loading

screenshots/6.png

33.7 KB
Loading

source/JJApplicationDelegate.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
@end
88

99
extern NSString*_Null_unspecified JJApplicationName;
10+
extern NSString*_Nonnull const UseSafariMenuItemSetting;
1011
extern NSString*_Nonnull const UseSafariTechnologyPreviewSetting;
1112
extern NSString*_Nonnull const SafariBundleID;
1213
extern NSString*_Nonnull const SafariTechnologyPreviewBundleID;

source/JJApplicationDelegate.m

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#import "JJMainWindow.h"
66

77
NSString* JJApplicationName;
8+
NSString*const UseSafariMenuItemSetting = @"UseSafariMenuItem";
89
NSString*const UseSafariTechnologyPreviewSetting = @"UseSafariTechnologyPreview";
910
NSString*const SafariBundleID = @"com.apple.Safari";
1011
NSString*const SafariTechnologyPreviewBundleID = @"com.apple.SafariTechnologyPreview";
@@ -38,6 +39,11 @@ -(void)applicationWillFinishLaunching:(nonnull NSNotification *)notification {
3839
NSLog(@"CFBundleName nil!");
3940
JJApplicationName = @PRODUCT_NAME;
4041
}
42+
NSString* defaultMenuItem = [@PRODUCT_NAME isEqualToString:@"PrivateWindow"] ? @"2" : @"1";
43+
[[NSUserDefaults standardUserDefaults] registerDefaults:@{
44+
UseSafariMenuItemSetting:defaultMenuItem,
45+
UseSafariTechnologyPreviewSetting:@NO
46+
}];
4147
[JJMainMenu populateMainMenu];
4248
}
4349

@@ -114,7 +120,7 @@ repeat while (count menu bars) = 0\n\
114120
end try\n\
115121
end if\n\
116122
end tell";
117-
NSString* menuItem = [@PRODUCT_NAME isEqualToString:@"PrivateWindow"] ? @"2" : @"1";
123+
NSString* menuItem = [[NSUserDefaults standardUserDefaults] stringForKey:UseSafariMenuItemSetting];
118124
NSString* safari = useSafariTechnologyPreview ? @"Safari Technology Preview" : @"Safari";
119125
NSString* source = [NSString stringWithFormat:formatString, safari, safari, menuItem];
120126
NSAppleScript* script = [[NSAppleScript alloc] initWithSource:source];

source/JJMainWindow.m

Lines changed: 78 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,14 @@ +(void)acessibilitySettings:(nullable id)sender {
99
AXIsProcessTrustedWithOptions((CFDictionaryRef)options);
1010
}
1111

12+
+(void)popUpAction:(nonnull NSPopUpButton*)popUp {
13+
NSMenuItem* selectedItem = [popUp selectedItem];
14+
if (selectedItem == nil)
15+
return;
16+
NSString* title = [selectedItem title];
17+
[[NSUserDefaults standardUserDefaults] setObject:title forKey:UseSafariMenuItemSetting];
18+
}
19+
1220
+(void)toggleBrowser:(nonnull NSButton*)sender {
1321
NSInteger tag = [sender tag];
1422
BOOL useSafariTechnologyPreview = tag == 1;
@@ -26,38 +34,54 @@ +(nonnull NSWindow*)window {
2634
NSView* contentView = [window contentView];
2735

2836
NSMutableArray<NSLayoutConstraint*>* constraints = [NSMutableArray array];
29-
[constraints addObject:[[contentView widthAnchor] constraintEqualToConstant:600.0]];
3037

3138
NSString* windowType = [JJApplicationName isEqualToString:@"PrivateWindow"] ? @"private" : @"non-private";
3239
NSString* intro = [NSString stringWithFormat:@"%@ opens URLs in a %@ window in your selected web browser and then quits.\nYou can set %@ as your default web brower in System Settings > Desktop & Dock.", JJApplicationName, windowType, JJApplicationName];
3340
NSTextField* label = [NSTextField wrappingLabelWithString:intro];
41+
[label setContentCompressionResistancePriority:NSLayoutPriorityDefaultHigh forOrientation:NSLayoutConstraintOrientationHorizontal];
3442
[label setTranslatesAutoresizingMaskIntoConstraints:NO];
3543
[contentView addSubview:label];
3644
[constraints addObject:[[label topAnchor] constraintEqualToAnchor:[contentView topAnchor] constant:JJMainWindowMargin]];
3745
[constraints addObject:[[label leadingAnchor] constraintEqualToAnchor:[contentView leadingAnchor] constant:JJMainWindowMargin]];
46+
[constraints addObject:[[contentView trailingAnchor] constraintEqualToAnchor:[label trailingAnchor] constant:JJMainWindowMargin]];
47+
48+
NSFont* font = [label font];
3849

3950
NSLayoutYAxisAnchor* bottomAnchor = [label bottomAnchor];
4051

52+
if (!AXIsProcessTrusted()) {
53+
NSString* trustString = [NSString stringWithFormat:@"You need to enable %@ in System Settings > Privacy & Security > Accessibility.", JJApplicationName];
54+
NSTextField* trustLabel = [NSTextField labelWithString:trustString];
55+
[trustLabel setTranslatesAutoresizingMaskIntoConstraints:NO];
56+
[contentView addSubview:trustLabel];
57+
[constraints addObject:[[trustLabel topAnchor] constraintEqualToAnchor:bottomAnchor constant:JJMainWindowMargin]];
58+
[constraints addObject:[[trustLabel leadingAnchor] constraintEqualToAnchor:[label leadingAnchor]]];
59+
60+
NSButton* trustButton = [[NSButton alloc] init];
61+
[trustButton setButtonType:NSButtonTypeMomentaryLight];
62+
[trustButton setBezelStyle:NSBezelStyleRounded];
63+
[trustButton setTitle:NSLocalizedString(@"Open Accessibility Settings", nil)];
64+
[trustButton setAction:@selector(acessibilitySettings:)];
65+
[trustButton setTarget:self];
66+
[trustButton setTranslatesAutoresizingMaskIntoConstraints:NO];
67+
[contentView addSubview:trustButton];
68+
[constraints addObject:[[trustButton topAnchor] constraintEqualToAnchor:[trustLabel bottomAnchor] constant:5.0]];
69+
[constraints addObject:[[trustButton leadingAnchor] constraintEqualToAnchor:[trustLabel leadingAnchor]]];
70+
[window setDefaultButtonCell:[trustButton cell]];
71+
[window setInitialFirstResponder:trustButton];
72+
bottomAnchor = [trustButton bottomAnchor];
73+
}
74+
4175
BOOL useSafariTechnologyPreview = [[NSUserDefaults standardUserDefaults] boolForKey:UseSafariTechnologyPreviewSetting];
4276
if (useSafariTechnologyPreview || [[NSWorkspace sharedWorkspace] URLForApplicationWithBundleIdentifier:SafariTechnologyPreviewBundleID] != nil) {
43-
NSTextField* browserLabel = [[NSTextField alloc] init];
44-
[browserLabel setBezeled:NO];
45-
[browserLabel setBordered:NO];
46-
[browserLabel setDrawsBackground:NO];
47-
[browserLabel setEditable:NO];
48-
[browserLabel setLineBreakMode:NSLineBreakByClipping];
49-
[browserLabel setSelectable:NO];
50-
[browserLabel setStringValue:@"Web Browser:"];
51-
[browserLabel setUsesSingleLineMode:YES];
77+
NSTextField* browserLabel = [NSTextField labelWithString:@"Web Browser:"];
5278
[browserLabel setTranslatesAutoresizingMaskIntoConstraints:NO];
5379
[contentView addSubview:browserLabel];
54-
[constraints addObject:[[browserLabel topAnchor] constraintEqualToAnchor:[label bottomAnchor] constant:JJMainWindowMargin]];
80+
[constraints addObject:[[browserLabel topAnchor] constraintEqualToAnchor:bottomAnchor constant:JJMainWindowMargin * 2.0]];
5581
[constraints addObject:[[browserLabel leadingAnchor] constraintEqualToAnchor:[label leadingAnchor]]];
5682

5783
bottomAnchor = [browserLabel bottomAnchor];
5884

59-
NSFont* font = [browserLabel font];
60-
6185
NSButton* safariButton = [NSButton radioButtonWithTitle:@"Safari" target:self action:@selector(toggleBrowser:)];
6286
[safariButton setTag:0];
6387
[safariButton setFont:font];
@@ -82,30 +106,48 @@ +(nonnull NSWindow*)window {
82106
[safariButton setState:NSControlStateValueOn];
83107
}
84108
}
109+
110+
NSTextField* popUpLabel = [NSTextField labelWithString:@"Safari File menu item:"];
111+
[popUpLabel setTranslatesAutoresizingMaskIntoConstraints:NO];
112+
[contentView addSubview:popUpLabel];
113+
[constraints addObject:[[popUpLabel topAnchor] constraintEqualToAnchor:bottomAnchor constant:JJMainWindowMargin * 2.0]];
114+
[constraints addObject:[[popUpLabel leadingAnchor] constraintEqualToAnchor:[label leadingAnchor]]];
85115

86-
if (!AXIsProcessTrusted()) {
87-
NSString* trustString = [NSString stringWithFormat:@"You need to enable %@ in System Settings > Privacy & Security > Accessibility.", JJApplicationName];
88-
NSTextField* trustLabel = [NSTextField labelWithString:trustString];
89-
[trustLabel setTranslatesAutoresizingMaskIntoConstraints:NO];
90-
[contentView addSubview:trustLabel];
91-
[constraints addObject:[[trustLabel topAnchor] constraintEqualToAnchor:bottomAnchor constant:JJMainWindowMargin]];
92-
[constraints addObject:[[trustLabel leadingAnchor] constraintEqualToAnchor:[label leadingAnchor]]];
93-
94-
NSButton* trustButton = [[NSButton alloc] init];
95-
[trustButton setButtonType:NSButtonTypeMomentaryLight];
96-
[trustButton setBezelStyle:NSBezelStyleRounded];
97-
[trustButton setTitle:NSLocalizedString(@"Open Accessibility Settings", nil)];
98-
[trustButton setAction:@selector(acessibilitySettings:)];
99-
[trustButton setTarget:self];
100-
[trustButton setTranslatesAutoresizingMaskIntoConstraints:NO];
101-
[contentView addSubview:trustButton];
102-
[constraints addObject:[[trustButton topAnchor] constraintEqualToAnchor:[trustLabel bottomAnchor] constant:5.0]];
103-
[constraints addObject:[[trustButton leadingAnchor] constraintEqualToAnchor:[trustLabel leadingAnchor]]];
104-
[window setDefaultButtonCell:[trustButton cell]];
105-
[window setInitialFirstResponder:trustButton];
106-
bottomAnchor = [trustButton bottomAnchor];
107-
}
108-
[constraints addObject:[[contentView bottomAnchor] constraintEqualToAnchor:bottomAnchor constant:JJMainWindowMargin]];
116+
NSPopUpButton * popUp = [[NSPopUpButton alloc] initWithFrame:NSMakeRect( 0.0, 0.0, 150.0, 16.0 ) pullsDown:NO];
117+
[popUp setFont:font];
118+
[popUp setAction:@selector(popUpAction:)];
119+
[popUp setTarget:self];
120+
[popUp setTranslatesAutoresizingMaskIntoConstraints:NO];
121+
[popUp addItemsWithTitles:@[@"1", @"2", @"3", @"4", @"5", @"6", @"7", @"8", @"9", @"10"]];
122+
NSString* menuItemTitle = [[NSUserDefaults standardUserDefaults] stringForKey:UseSafariMenuItemSetting];
123+
[popUp selectItemWithTitle:menuItemTitle];
124+
[contentView addSubview:popUp];
125+
[constraints addObject:[[popUp leadingAnchor] constraintEqualToAnchor:[popUpLabel trailingAnchor] constant:5.0]];
126+
[constraints addObject:[[popUp lastBaselineAnchor] constraintEqualToAnchor:[popUpLabel lastBaselineAnchor]]];
127+
128+
NSTextField* popUpInstructions = [NSTextField labelWithString:@"By default, item 1 in the Safari File menu is New Window, and item 2 is New Private Window.\nHowever, Safari Profiles add items to the menu. Select the menu item that you want to use."];
129+
[popUpInstructions setTranslatesAutoresizingMaskIntoConstraints:NO];
130+
[contentView addSubview:popUpInstructions];
131+
[constraints addObject:[[popUpInstructions topAnchor] constraintEqualToAnchor:[popUp bottomAnchor] constant:10.0]];
132+
[constraints addObject:[[popUpInstructions leadingAnchor] constraintEqualToAnchor:[label leadingAnchor]]];
133+
134+
NSImage* screenshot1 = [NSImage imageNamed:@"FileDefault"];
135+
NSImageView* imageView1 = [[NSImageView alloc] init];
136+
[imageView1 setImage:screenshot1];
137+
[imageView1 setTranslatesAutoresizingMaskIntoConstraints:NO];
138+
[contentView addSubview:imageView1];
139+
[constraints addObject:[[imageView1 topAnchor] constraintEqualToAnchor:[popUpInstructions bottomAnchor] constant:10.0]];
140+
[constraints addObject:[[imageView1 leadingAnchor] constraintEqualToAnchor:[label leadingAnchor]]];
141+
142+
NSImage* screenshot2 = [NSImage imageNamed:@"FileProfiles"];
143+
NSImageView* imageView2 = [[NSImageView alloc] init];
144+
[imageView2 setImage:screenshot2];
145+
[imageView2 setTranslatesAutoresizingMaskIntoConstraints:NO];
146+
[contentView addSubview:imageView2];
147+
[constraints addObject:[[imageView2 topAnchor] constraintEqualToAnchor:[imageView1 topAnchor]]];
148+
[constraints addObject:[[imageView2 leadingAnchor] constraintEqualToAnchor:[imageView1 trailingAnchor] constant:JJMainWindowMargin]];
149+
150+
[constraints addObject:[[contentView bottomAnchor] constraintEqualToAnchor:[imageView2 bottomAnchor] constant:JJMainWindowMargin]];
109151
[NSLayoutConstraint activateConstraints:constraints];
110152

111153
[window makeKeyAndOrderFront:nil];

0 commit comments

Comments
 (0)