Tk Source Code

Check-in [a7e34ff9]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Code and data type cleanup, thanks to Marc Culler for patch
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | mac_services
Files: files | file ages | folders
SHA3-256: a7e34ff9cec93f6354d6de80aa0c9d674a2c2d3ffb12fbf4920a605801239a9a
User & Date: kevin_walzer 2019-05-17 03:13:34.546
Context
2019-05-18
13:05
Finally got timing of initializing NSServices object correct; code cleanup; merge in 8.6 to pick up changes in Tk initialization code check-in: f126b00e user: kevin_walzer tags: mac_services
2019-05-17
03:13
Code and data type cleanup, thanks to Marc Culler for patch check-in: a7e34ff9 user: kevin_walzer tags: mac_services
2019-05-12
02:03
Restore deprecated call to NSPasteboardTypeString in writeSelectiontoPasteboard because it breaks sending data to the services menu. Data type must be identical in this call and in the NSSendTypes key in info.plist; we cannot do a clever mapping here of the old type to a new one because the info.plist does not have this kind of conditional reading on different versions of macOS. We will have to live with the deprecated call until it is obsolete/removed altogether by Apple. check-in: 42577ce4 user: kevin_walzer tags: mac_services
Changes
Unified Diff Ignore Whitespace Patch
Changes to macosx/Wish-Info.plist.in.
102
103
104
105
106
107
108

109
110
111
112
113
114
115
            <key>NSMessage</key>
            <string>provideService</string>
            <key>NSPortName</key>
            <string>Wish</string>

            <key>NSSendTypes</key>
            <array>

                <string>NSPasteboardTypeString</string>
            </array>
        </dict>
    </array>

</dict>
</plist>







>







102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
            <key>NSMessage</key>
            <string>provideService</string>
            <key>NSPortName</key>
            <string>Wish</string>

            <key>NSSendTypes</key>
            <array>
                <string>NSStringPboardType</string>
                <string>NSPasteboardTypeString</string>
            </array>
        </dict>
    </array>

</dict>
</plist>
Changes to macosx/tkMacOSXInit.c.
112
113
114
115
116
117
118

119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
     */
    TkMacOSXUseAntialiasedText(_eventInterp, -1);
    TkMacOSXInitCGDrawing(_eventInterp, TRUE, 0);
}

-(void)applicationDidFinishLaunching:(NSNotification *)notification
{

    /*
     * It is not safe to force activation of the NSApp until this method is
     * called. Activating too early can cause the menu bar to be unresponsive.
     */

    [NSApp activateIgnoringOtherApps: YES];

    /*
     * Process events to ensure that the root window is fully initialized. See
     * ticket 56a1823c73.
     */

    [NSApp _lockAutoreleasePool];
    while (Tcl_DoOneEvent(TCL_WINDOW_EVENTS| TCL_DONT_WAIT)) {}
    [NSApp _unlockAutoreleasePool];

    Tk_MacOSXServices_Init(_eventInterp);
}

- (void) _setup: (Tcl_Interp *) interp
{
    /*
     * Remember our interpreter.
     */







>















|
|







112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
     */
    TkMacOSXUseAntialiasedText(_eventInterp, -1);
    TkMacOSXInitCGDrawing(_eventInterp, TRUE, 0);
}

-(void)applicationDidFinishLaunching:(NSNotification *)notification
{

    /*
     * It is not safe to force activation of the NSApp until this method is
     * called. Activating too early can cause the menu bar to be unresponsive.
     */

    [NSApp activateIgnoringOtherApps: YES];

    /*
     * Process events to ensure that the root window is fully initialized. See
     * ticket 56a1823c73.
     */

    [NSApp _lockAutoreleasePool];
    while (Tcl_DoOneEvent(TCL_WINDOW_EVENTS| TCL_DONT_WAIT)) {}
    [NSApp _unlockAutoreleasePool];
    
    TkMacOSXServices_Init(_eventInterp);
}

- (void) _setup: (Tcl_Interp *) interp
{
    /*
     * Remember our interpreter.
     */
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
  /* Convert the URL reference into a string reference. */
  CFStringRef appPath = CFURLCopyFileSystemPath(mainBundleURL, kCFURLPOSIXPathStyle);
 
  /* Get the system encoding method. */
  CFStringEncoding encodingMethod = CFStringGetSystemEncoding();
 
  /* Convert the string reference into a C string. */
  char *path = CFStringGetCStringPtr(appPath, encodingMethod);

  Tcl_SetResult(ip, path, NULL);

  CFRelease(mainBundleURL);
  CFRelease(appPath);
  return TCL_OK;








|







446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
  /* Convert the URL reference into a string reference. */
  CFStringRef appPath = CFURLCopyFileSystemPath(mainBundleURL, kCFURLPOSIXPathStyle);
 
  /* Get the system encoding method. */
  CFStringEncoding encodingMethod = CFStringGetSystemEncoding();
 
  /* Convert the string reference into a C string. */
  char *path = (char *) CFStringGetCStringPtr(appPath, encodingMethod);

  Tcl_SetResult(ip, path, NULL);

  CFRelease(mainBundleURL);
  CFRelease(appPath);
  return TCL_OK;

Changes to macosx/tkMacOSXPrivate.h.
229
230
231
232
233
234
235



236
237
238
239
240
241
242
			    NSWindow *macWindow);
MODULE_SCOPE int	TkMacOSXStandardAboutPanelObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
MODULE_SCOPE int	TkMacOSXIconBitmapObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);



MODULE_SCOPE int	TkMacOSXRegisterServiceWidgetObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);

#pragma mark Private Objective-C Classes

#define VISIBILITY_HIDDEN __attribute__((visibility("hidden")))







>
>
>







229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
			    NSWindow *macWindow);
MODULE_SCOPE int	TkMacOSXStandardAboutPanelObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
MODULE_SCOPE int	TkMacOSXIconBitmapObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
MODULE_SCOPE void       TkMacOSXDrawSolidBorder(Tk_Window tkwin, GC gc,
			    int inset, int thickness);
MODULE_SCOPE int 	TkMacOSXServices_Init(Tcl_Interp *interp);
MODULE_SCOPE int	TkMacOSXRegisterServiceWidgetObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);

#pragma mark Private Objective-C Classes

#define VISIBILITY_HIDDEN __attribute__((visibility("hidden")))
333
334
335
336
337
338
339

340
341
342
343
344
345
346
347
348
- (void)handleURLEvent:                (NSAppleEventDescriptor*)event
	           withReplyEvent:     (NSAppleEventDescriptor*)replyEvent;
@end

VISIBILITY_HIDDEN
@interface TKContentView : NSView <NSTextInput>
{

    NSString *privateWorkingText;
    #ifdef __i386__
    /* The Objective C runtime used on i386 requires this. */
    Bool _needsRedisplay;
#endif
}
@property Bool needsRedisplay;
@end








>

|







336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
- (void)handleURLEvent:                (NSAppleEventDescriptor*)event
	           withReplyEvent:     (NSAppleEventDescriptor*)replyEvent;
@end

VISIBILITY_HIDDEN
@interface TKContentView : NSView <NSTextInput>
{
@private
    NSString *privateWorkingText;
#ifdef __i386__
    /* The Objective C runtime used on i386 requires this. */
    Bool _needsRedisplay;
#endif
}
@property Bool needsRedisplay;
@end

Changes to macosx/tkMacOSXServices.c.
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64

65
66
67
68
69
70
71
/*
 * Class methods.
 */

@implementation TkService

+ (void) initialize {
    NSArray *sendTypes = [NSArray arrayWithObjects:NSPasteboardTypeString, nil];

    [NSApp registerServicesMenuSendTypes:sendTypes returnTypes:nil];
    NSUpdateDynamicServices();
    return;
}


- (id)validRequestorForSendType:(NSString *)sendType
		     returnType:(NSString *)returnType
{
    if ([sendType isEqual:NSStringPboardType]) {

	return self;
    }
    return [super validRequestorForSendType:sendType returnType:returnType];
}

/*
 * Make sure the view accepts events.







|
|
|








|
>







46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
/*
 * Class methods.
 */

@implementation TkService

+ (void) initialize {
    NSArray *sendTypes = [NSArray arrayWithObjects:@"NSStringPboardType",
				  @"NSPasteboardTypeString", nil];
    [NSApp registerServicesMenuSendTypes:sendTypes returnTypes:sendTypes];
    NSUpdateDynamicServices();
    return;
}


- (id)validRequestorForSendType:(NSString *)sendType
		     returnType:(NSString *)returnType
{
    if ([sendType isEqualToString:@"NSStringPboardType"] ||
	[sendType isEqualToString:@"NSPasteboardTypeString"]) {
	return self;
    }
    return [super validRequestorForSendType:sendType returnType:returnType];
}

/*
 * Make sure the view accepts events.
83
84
85
86
87
88
89
90


91



92
93
94



95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123

124

125


126


127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
/*
 * Get selected text, copy to pasteboard.
 */

- (BOOL)writeSelectionToPasteboard:(NSPasteboard *)pboard
			     types:(NSArray *)types
{
    NSArray *typesDeclared;


    if ([types containsObject:NSStringPboardType] == NO) {



	return NO;
    }




    Tcl_Eval(ServicesInterp,"selection get");
    char *copystring;
    copystring = Tcl_GetString(Tcl_GetObjResult(ServicesInterp));

    NSString *writestring = [NSString stringWithUTF8String:copystring];
    typesDeclared = [NSArray arrayWithObject:NSStringPboardType];
    [pboard declareTypes:typesDeclared owner:nil];
    return [pboard setString:writestring forType:NSPasteboardTypeString];
}


/*
 * This is the method that actually calls the Tk service; this is the method
 * that must be defined in info.plist.
 */

- (void)provideService:(NSPasteboard *)pboard
	      userData:(NSString *)data
		 error:(NSString **)error
{
    NSString *pboardString;
    NSArray *types = [pboard types];
    Tcl_Event *event;

    /*
     * Get string from private pasteboard, write to general pasteboard to make
     * available to Tcl service.
     */


    if ([types containsObject:NSStringPboardType] &&

	(pboardString = [pboard stringForType:NSStringPboardType])) {





	NSPasteboard *generalpasteboard = [NSPasteboard generalPasteboard];
	[generalpasteboard declareTypes:[NSArray
	     arrayWithObjects:NSStringPboardType, nil] owner:nil];
	[generalpasteboard setString:pboardString forType: NSPasteboardTypeString];
	event = ckalloc(sizeof(Tcl_Event));
	event->proc = ServicesEventProc;
	Tcl_QueueEvent((Tcl_Event *)event, TCL_QUEUE_TAIL);
    }
}

@end


/*
 * Register a specific widget to access the Services menu.
 */








|
>
>
|
>
>
>
|
|
|
>
>
>





<

|












|








>
|
>
|
>
>
|
>
>

|
|
|





<







84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108

109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149

150
151
152
153
154
155
156
/*
 * Get selected text, copy to pasteboard.
 */

- (BOOL)writeSelectionToPasteboard:(NSPasteboard *)pboard
			     types:(NSArray *)types
{
    NSArray *typesDeclared = nil;
    NSString *pboardType = nil;
    for (NSString *typeString in types) {
	if ([typeString isEqualToString:@"NSStringPboardType"] ||
	    [typeString isEqualToString:@"NSPasteboardTypeString"]) {
	    typesDeclared = [NSArray arrayWithObject:typeString];
	    pboardType = typeString;
	    break;
	}
    }
    if (!typesDeclared) {
	return NO;
    }
    Tcl_Eval(ServicesInterp,"selection get");
    char *copystring;
    copystring = Tcl_GetString(Tcl_GetObjResult(ServicesInterp));

    NSString *writestring = [NSString stringWithUTF8String:copystring];

    [pboard declareTypes:typesDeclared owner:nil];
    return [pboard setString:writestring forType:pboardType];
}


/*
 * This is the method that actually calls the Tk service; this is the method
 * that must be defined in info.plist.
 */

- (void)provideService:(NSPasteboard *)pboard
	      userData:(NSString *)data
		 error:(NSString **)error
{
    NSString *pboardString, *pboardType;
    NSArray *types = [pboard types];
    Tcl_Event *event;

    /*
     * Get string from private pasteboard, write to general pasteboard to make
     * available to Tcl service.
     */

    for (NSString *typeString in types) {
	if ([typeString isEqualToString:@"NSStringPboardType"] ||
	    [typeString isEqualToString:@"NSPasteboardTypeString"]) {
	    pboardString = [pboard stringForType:typeString];
	    pboardType = typeString;
	    break;
	}
    }
    if (pboardString) {
	NSPasteboard *generalpasteboard = [NSPasteboard generalPasteboard];
	[generalpasteboard declareTypes:[NSArray arrayWithObjects:pboardType, nil]
				  owner:nil];
	[generalpasteboard setString:pboardString forType:pboardType];
	event = ckalloc(sizeof(Tcl_Event));
	event->proc = ServicesEventProc;
	Tcl_QueueEvent((Tcl_Event *)event, TCL_QUEUE_TAIL);
    }
}

@end


/*
 * Register a specific widget to access the Services menu.
 */

201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
    return TCL_OK;
}

/*
 * Initalize the package in the tcl interpreter, create tcl commands.
 */

int Tk_MacOSXServices_Init(
    Tcl_Interp *interp)
{
    /*
     * Set up an autorelease pool.
     */

    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];







|







214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
    return TCL_OK;
}

/*
 * Initalize the package in the tcl interpreter, create tcl commands.
 */

int TkMacOSXServices_Init(
    Tcl_Interp *interp)
{
    /*
     * Set up an autorelease pool.
     */

    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];