Skip to content

Commit 6809ac3

Browse files
committed
Prettify the SSH password window
- use something close to the standard HIG spacing - add the app's icon and a title so people know what app is asking for a password - save the position of the window and only center the window if the user hasn't moved it before - the NSSecureTextField spews some garbage to STDERR which GitX would show in the success/failure sheet so close STDERR
1 parent a6b5705 commit 6809ac3

File tree

1 file changed

+61
-45
lines changed

1 file changed

+61
-45
lines changed

gitx_askpasswd_main.m

+61-45
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,10 @@
1616
#define CANCELBUTTONHEIGHT 24.0
1717
#define PASSHEIGHT 22.0
1818
#define PASSLABELHEIGHT 16.0
19+
#define WINDOWAUTOSAVENAME @"GitXAskPasswordWindowFrame"
1920

2021

21-
@interface GAPAppDelegate : NSObject <NSApplicationDelegate>
22+
@interface GAPAppDelegate : NSObject
2223
{
2324
NSPanel* mPasswordPanel;
2425
NSSecureTextField* mPasswordField;
@@ -34,38 +35,31 @@ -(IBAction) doCancelButton: (id)sender;
3435

3536
@implementation GAPAppDelegate
3637

37-
-(void) dealloc
38-
{
39-
[mPasswordPanel release];
40-
mPasswordPanel = nil;
41-
42-
[mPasswordField release];
43-
mPasswordField = nil;
44-
45-
[super dealloc];
46-
}
47-
4838
-(NSPanel*) passwordPanel
4939
{
5040
if( !mPasswordPanel )
5141
{
52-
NSRect box = NSMakeRect( 100, 100, 250, 100 );
42+
NSRect box = NSMakeRect( 100, 100, 400, 134 );
5343
mPasswordPanel = [[NSPanel alloc] initWithContentRect: box
54-
styleMask: NSTitledWindowMask
55-
backing: NSBackingStoreBuffered defer: NO];
44+
styleMask: NSTitledWindowMask
45+
backing: NSBackingStoreBuffered defer: NO];
5646
[mPasswordPanel setHidesOnDeactivate: NO];
5747
[mPasswordPanel setLevel: NSFloatingWindowLevel];
58-
[mPasswordPanel center];
48+
[mPasswordPanel setTitle: @"GitX SSH Remote Login"];
49+
if (![mPasswordPanel setFrameUsingName: WINDOWAUTOSAVENAME]) {
50+
[mPasswordPanel center];
51+
[mPasswordPanel setFrameAutosaveName: WINDOWAUTOSAVENAME];
52+
}
5953

6054
box.origin = NSZeroPoint; // Only need local coords from now on.
6155

6256
// OK:
63-
NSRect okBox = box;
64-
okBox.origin.x = NSMaxX( box ) -OKBUTTONWIDTH -10;
57+
NSRect okBox = box;
58+
okBox.origin.x = NSMaxX( box ) -OKBUTTONWIDTH -20;
6559
okBox.size.width = OKBUTTONWIDTH;
66-
okBox.origin.y += 10;
60+
okBox.origin.y += 20;
6761
okBox.size.height = OKBUTTONHEIGHT;
68-
NSButton* okButton = [[[NSButton alloc] initWithFrame: okBox] autorelease];
62+
NSButton *okButton = [[NSButton alloc] initWithFrame: okBox];
6963
[okButton setTarget: self];
7064
[okButton setAction: @selector(doOKButton:)];
7165
[okButton setTitle: @"OK"]; // +++ Localize.
@@ -78,22 +72,22 @@ -(NSPanel*) passwordPanel
7872
NSRect cancelBox = box;
7973
cancelBox.origin.x = NSMinX( okBox ) -CANCELBUTTONWIDTH -6;
8074
cancelBox.size.width = CANCELBUTTONWIDTH;
81-
cancelBox.origin.y += 10;
75+
cancelBox.origin.y += 20;
8276
cancelBox.size.height = CANCELBUTTONHEIGHT;
83-
okButton = [[[NSButton alloc] initWithFrame: cancelBox] autorelease];
84-
[okButton setTarget: self];
85-
[okButton setAction: @selector(doCancelButton:)];
86-
[okButton setTitle: @"Cancel"]; // +++ Localize.
87-
[okButton setBordered: YES];
88-
[okButton setBezelStyle: NSRoundedBezelStyle];
89-
[[mPasswordPanel contentView] addSubview: okButton];
77+
NSButton *cancleButton = [[NSButton alloc] initWithFrame: cancelBox];
78+
[cancleButton setTarget: self];
79+
[cancleButton setAction: @selector(doCancelButton:)];
80+
[cancleButton setTitle: @"Cancel"]; // +++ Localize.
81+
[cancleButton setBordered: YES];
82+
[cancleButton setBezelStyle: NSRoundedBezelStyle];
83+
[[mPasswordPanel contentView] addSubview: cancleButton];
9084

9185
// Password field:
92-
NSRect passBox = box;
93-
passBox.origin.y = NSMaxY(okBox) + 12;
86+
NSRect passBox = box;
87+
passBox.origin.y = NSMaxY(okBox) + 24;
9488
passBox.size.height = PASSHEIGHT;
95-
passBox.origin.x += 12;
96-
passBox.size.width -= 12 * 2;
89+
passBox.origin.x += 104;
90+
passBox.size.width -= 104 + 20;
9791
mPasswordField = [[NSSecureTextField alloc] initWithFrame: passBox];
9892
[mPasswordField setSelectable: YES];
9993
[mPasswordField setEditable: YES];
@@ -104,19 +98,32 @@ -(NSPanel*) passwordPanel
10498
[[mPasswordPanel contentView] addSubview: mPasswordField];
10599

106100
// Password label:
107-
NSRect passLabelBox = box;
108-
passLabelBox.origin.y = NSMaxY(passBox) + 6;
101+
NSRect passLabelBox = box;
102+
passLabelBox.origin.y = NSMaxY(passBox) + 8;
109103
passLabelBox.size.height = PASSLABELHEIGHT;
110-
passLabelBox.origin.x += 12;
111-
passLabelBox.size.width -= 12 * 2;
112-
NSTextField* passwordLabel = [[[NSTextField alloc] initWithFrame: passLabelBox] autorelease];
104+
passLabelBox.origin.x += 100;
105+
passLabelBox.size.width -= 100 + 20;
106+
NSTextField *passwordLabel = [[NSTextField alloc] initWithFrame: passLabelBox];
113107
[passwordLabel setSelectable: YES];
114108
[passwordLabel setEditable: NO];
115109
[passwordLabel setBordered: NO];
116110
[passwordLabel setBezeled: NO];
117111
[passwordLabel setDrawsBackground: NO];
118112
[passwordLabel setStringValue: @"Please enter your password:"]; // +++ Localize.
119113
[[mPasswordPanel contentView] addSubview: passwordLabel];
114+
115+
// GitX icon:
116+
NSRect gitxIconBox = box;
117+
gitxIconBox.origin.y = NSMaxY(box) - 78;
118+
gitxIconBox.size.height = 64;
119+
gitxIconBox.origin.x += 20;
120+
gitxIconBox.size.width = 64;
121+
NSImageView *gitxIconView = [[NSImageView alloc] initWithFrame: gitxIconBox];
122+
[gitxIconView setEditable: NO];
123+
NSString *gitxIconPath = [[[NSBundle mainBundle] bundlePath] stringByAppendingPathComponent: @"gitx.icns"];
124+
NSImage *gitxIcon = [[NSImage alloc] initWithContentsOfFile: gitxIconPath];
125+
[gitxIconView setImage: gitxIcon];
126+
[[mPasswordPanel contentView] addSubview: gitxIconView];
120127
}
121128

122129
return mPasswordPanel;
@@ -126,14 +133,16 @@ -(NSPanel*) passwordPanel
126133
-(IBAction) doOKButton: (id)sender
127134
{
128135
printf( "%s\n", [[mPasswordField stringValue] UTF8String] );
129-
[[NSApplication sharedApplication] terminate: self];
136+
[[NSApplication sharedApplication] stopModalWithCode: 0];
130137
}
131138

132139

140+
// TODO: Need to find out how to get SSH to cancel.
141+
// When the user cancels the window it is opened again for however
142+
// many times the remote server allows failed attempts.
133143
-(IBAction) doCancelButton: (id)sender
134144
{
135-
printf("\n");
136-
[[NSApplication sharedApplication] terminate: self];
145+
[[NSApplication sharedApplication] stopModalWithCode: 1];
137146
}
138147

139148
@end
@@ -142,18 +151,25 @@ -(IBAction) doCancelButton: (id)sender
142151

143152
int main( int argc, const char** argv )
144153
{
154+
// close stderr to stop cocoa log messages from being picked up by GitX
155+
close(STDERR_FILENO);
156+
157+
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
158+
145159
ProcessSerialNumber myPSN = { 0, kCurrentProcess };
146160
TransformProcessType( &myPSN, kProcessTransformToForegroundApplication );
147161

148-
NSApplication * app = [NSApplication sharedApplication];
149-
GAPAppDelegate * appDel = [[GAPAppDelegate alloc] init];
162+
NSApplication *app = [NSApplication sharedApplication];
163+
GAPAppDelegate *appDel = [[GAPAppDelegate alloc] init];
150164
[app setDelegate: appDel];
151-
NSWindow* passPanel = [appDel passwordPanel];
165+
NSWindow *passPanel = [appDel passwordPanel];
152166

153167
[app activateIgnoringOtherApps: YES];
154168
[passPanel makeKeyAndOrderFront: nil];
155-
[app runModalForWindow: passPanel];
169+
NSInteger code = [app runModalForWindow: passPanel];
170+
171+
[defaults synchronize];
156172

157-
return 0;
173+
return code;
158174
}
159175

0 commit comments

Comments
 (0)