Check-in [d751ac6185]
Not logged in

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

Overview
Comment:merge with trunk
Timelines: family | ancestors | descendants | both | wtf-8-experiment
Files: files | file ages | folders
SHA1: d751ac61851b7c3106db8bbd70cb822166fc44ee
User & Date: chw 2019-07-02 04:07:47.852
Context
2019-07-04
15:32
merge with trunk check-in: d5ad5781d6 user: chw tags: wtf-8-experiment
2019-07-02
04:07
merge with trunk check-in: d751ac6185 user: chw tags: wtf-8-experiment
04:06
add tcl upstream changes check-in: 3567d254c3 user: chw tags: trunk
2019-06-28
10:45
merge with trunk check-in: 42766a9a25 user: chw tags: wtf-8-experiment
Changes
Unified Diff Ignore Whitespace Patch
Changes to jni/sdl2tk/doc/tk_mac.n.
9
10
11
12
13
14
15


16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34

35
36
37
38
39
40
41
42
43
44
45














46
47
48
49
50
51
52
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
tk::mac \- Access Mac-Specific Functionality on OS X from Tk
.SH SYNOPSIS
.nf


\fB::tk::mac::ShowPreferences\fR
\fB::tk::mac::OpenApplication\fR
\fB::tk::mac::ReopenApplication\fR
\fB::tk::mac::OpenDocument \fIfile...\fR
\fB::tk::mac::PrintDocument \fIfile...\fR
\fB::tk::mac::Quit\fR
\fB::tk::mac::OnHide\fR
\fB::tk::mac::OnShow\fR
\fB::tk::mac::ShowHelp\fR
\fB::tk::mac::PerformService\fR
\fB::tk::mac::LaunchURL \fIURL...\fR
\fB::tk::mac::GetAppPath\fR

\fB::tk::mac::standardAboutPanel\fR

\fB::tk::mac::useCompatibilityMetrics \fIboolean\fR
\fB::tk::mac::CGAntialiasLimit \fIlimit\fR
\fB::tk::mac::antialiasedtext \fInumber\fR
\fB::tk::mac::useThemedToplevel \fIboolean\fR


\fB::tk::mac::iconBitmap \fIname width height \-kind value\fR
.fi
.BE
.SH "EVENT HANDLER CALLBACKS"
.PP
The Aqua/Mac OS X application environment defines a number of additional
events that applications should respond to. These events are mapped by Tk to
calls to commands in the \fB::tk::mac\fR namespace; unless otherwise noted, if
the command is absent, no action will be taken.
.TP














\fB::tk::mac::ShowPreferences\fR
.
The default Apple Event handler for kAEShowPreferences,
.QW pref .
The application menu
.QW "Preferences"
menu item is only enabled when this proc is defined. Typically this command is







>
>



















>











>
>
>
>
>
>
>
>
>
>
>
>
>
>







9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
tk::mac \- Access Mac-Specific Functionality on OS X from Tk
.SH SYNOPSIS
.nf
\fB::tk::mac::DoScriptFile\fR
\fB::tk::mac::DoScriptText\fR
\fB::tk::mac::ShowPreferences\fR
\fB::tk::mac::OpenApplication\fR
\fB::tk::mac::ReopenApplication\fR
\fB::tk::mac::OpenDocument \fIfile...\fR
\fB::tk::mac::PrintDocument \fIfile...\fR
\fB::tk::mac::Quit\fR
\fB::tk::mac::OnHide\fR
\fB::tk::mac::OnShow\fR
\fB::tk::mac::ShowHelp\fR
\fB::tk::mac::PerformService\fR
\fB::tk::mac::LaunchURL \fIURL...\fR
\fB::tk::mac::GetAppPath\fR

\fB::tk::mac::standardAboutPanel\fR

\fB::tk::mac::useCompatibilityMetrics \fIboolean\fR
\fB::tk::mac::CGAntialiasLimit \fIlimit\fR
\fB::tk::mac::antialiasedtext \fInumber\fR
\fB::tk::mac::useThemedToplevel \fIboolean\fR


\fB::tk::mac::iconBitmap \fIname width height \-kind value\fR
.fi
.BE
.SH "EVENT HANDLER CALLBACKS"
.PP
The Aqua/Mac OS X application environment defines a number of additional
events that applications should respond to. These events are mapped by Tk to
calls to commands in the \fB::tk::mac\fR namespace; unless otherwise noted, if
the command is absent, no action will be taken.
.TP
\fB::tk::mac::DoScriptFile\fR
.
The default Apple Event handler for AEDoScriptHandler. This command,
if defined, executes a Tcl file when an AppleScript sends a
.QW "do script"
command to Wish with a file path as a parameter. 
.TP
\fB::tk::mac::DoScriptText\fR
.
The default Apple Event handler for AEDoScriptHandler. This command,
if defined, executes Tcl code when an AppleScript sends a
.QW "do script"
command to Wish with Tcl code or a Tcl procedure as a parameter.
.TP
\fB::tk::mac::ShowPreferences\fR
.
The default Apple Event handler for kAEShowPreferences,
.QW pref .
The application menu
.QW "Preferences"
menu item is only enabled when this proc is defined. Typically this command is
Changes to jni/sdl2tk/library/menu.tcl.
83
84
85
86
87
88
89





90
91
92
93
94
95
96

bind Menubutton <FocusIn> {}
bind Menubutton <Enter> {
    tk::MbEnter %W
}
bind Menubutton <Leave> {
    tk::MbLeave %W





}
bind Menubutton <1> {
    if {$tk::Priv(inMenubutton) ne ""} {
	tk::MbPost $tk::Priv(inMenubutton) %X %Y
    }
}
bind Menubutton <Motion> {







>
>
>
>
>







83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101

bind Menubutton <FocusIn> {}
bind Menubutton <Enter> {
    tk::MbEnter %W
}
bind Menubutton <Leave> {
    tk::MbLeave %W
}
if {$::tk::android} {
    bind Menubutton <<FingerUp>> {
	if {%s == 1} {tk::MbLeave %W}
    }
}
bind Menubutton <1> {
    if {$tk::Priv(inMenubutton) ne ""} {
	tk::MbPost $tk::Priv(inMenubutton) %X %Y
    }
}
bind Menubutton <Motion> {
278
279
280
281
282
283
284



285
286
287
288
289
290
291
    if {$::tk_strictMotif} {
        set Priv(cursor) [$w cget -cursor]
        $w configure -cursor arrow
    }
    if {[tk windowingsystem] ne "aqua"} {
	set Priv(relief) [$w cget -relief]
	$w configure -relief raised



    } else {
	$w configure -state active
    }

    set Priv(postedMb) $w
    set Priv(focus) [focus]
    $menu activate none







>
>
>







283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
    if {$::tk_strictMotif} {
        set Priv(cursor) [$w cget -cursor]
        $w configure -cursor arrow
    }
    if {[tk windowingsystem] ne "aqua"} {
	set Priv(relief) [$w cget -relief]
	$w configure -relief raised
	if {[$w cget -state] ne "active"} {
	    $w configure -state active
	}
    } else {
	$w configure -state active
    }

    set Priv(postedMb) $w
    set Priv(focus) [focus]
    $menu activate none
Changes to jni/sdl2tk/library/ttk/menubutton.tcl.
46
47
48
49
50
51
52





53
54
55
56
57
58
59

bind TMenubutton <Enter>	{ %W instate !disabled {%W state active } }
bind TMenubutton <Leave>	{ %W state !active }
bind TMenubutton <Key-space> 	{ ttk::menubutton::Popdown %W }
bind TMenubutton <<Invoke>> 	{ ttk::menubutton::Popdown %W }

if {[tk windowingsystem] eq "x11"} {





    bind TMenubutton <ButtonPress-1>  	{ ttk::menubutton::Pulldown %W }
    bind TMenubutton <ButtonRelease-1>	{ ttk::menubutton::TransferGrab %W }
    bind TMenubutton <B1-Leave> 	{ ttk::menubutton::TransferGrab %W }
} else {
    bind TMenubutton <ButtonPress-1>  \
	{ %W state pressed ; ttk::menubutton::Popdown %W }
    bind TMenubutton <ButtonRelease-1>  \







>
>
>
>
>







46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64

bind TMenubutton <Enter>	{ %W instate !disabled {%W state active } }
bind TMenubutton <Leave>	{ %W state !active }
bind TMenubutton <Key-space> 	{ ttk::menubutton::Popdown %W }
bind TMenubutton <<Invoke>> 	{ ttk::menubutton::Popdown %W }

if {[tk windowingsystem] eq "x11"} {
    if {$::tk::android} {
	bind TMenubutton <<FingerUp>> {
	    if {%s == 1} { %W instate active { %W state !active } }
	}
    }
    bind TMenubutton <ButtonPress-1>  	{ ttk::menubutton::Pulldown %W }
    bind TMenubutton <ButtonRelease-1>	{ ttk::menubutton::TransferGrab %W }
    bind TMenubutton <B1-Leave> 	{ ttk::menubutton::TransferGrab %W }
} else {
    bind TMenubutton <ButtonPress-1>  \
	{ %W state pressed ; ttk::menubutton::Popdown %W }
    bind TMenubutton <ButtonRelease-1>  \
188
189
190
191
192
193
194

195
196
197
198
199
200
201
proc ttk::menubutton::Pulldown {mb} {
    variable State
    if {[$mb instate disabled] || [set menu [$mb cget -menu]] eq ""} {
	return
    }
    set State(pulldown) 1
    set State(oldcursor) [$mb cget -cursor]


    $mb state pressed
    $mb configure -cursor [$menu cget -cursor]
    foreach {x y entry} [PostPosition $mb $menu] { break }
    if {$entry ne {}} {
	$menu post $x $y $entry
    } else {







>







193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
proc ttk::menubutton::Pulldown {mb} {
    variable State
    if {[$mb instate disabled] || [set menu [$mb cget -menu]] eq ""} {
	return
    }
    set State(pulldown) 1
    set State(oldcursor) [$mb cget -cursor]
    $mb instate !active { $mb state active }

    $mb state pressed
    $mb configure -cursor [$menu cget -cursor]
    foreach {x y entry} [PostPosition $mb $menu] { break }
    if {$entry ne {}} {
	$menu post $x $y $entry
    } else {
Changes to jni/sdl2tk/macosx/tkMacOSXKeyEvent.c.
255
256
257
258
259
260
261
262

263
264
265
266
267
268
269
}
@end


@implementation TKContentView

-(id)init {
    if (self = [super init]) {

        _needsRedisplay = NO;
    }
    return self;
}

/* <NSTextInput> implementation (called through interpretKeyEvents:]). */








|
>







255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
}
@end


@implementation TKContentView

-(id)init {
    self = [super init];
    if (self) {
        _needsRedisplay = NO;
    }
    return self;
}

/* <NSTextInput> implementation (called through interpretKeyEvents:]). */

Changes to jni/sdl2tk/macosx/tkMacOSXMouseEvent.c.
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
 */

@implementation TKApplication(TKMouseEvent)
- (NSEvent *) tkProcessMouseEvent: (NSEvent *) theEvent
{
    NSWindow *eventWindow = [theEvent window];
    NSEventType eventType = [theEvent type];
    TkWindow *winPtr, *grabWinPtr;
    Tk_Window tkwin;
    NSPoint local, global;
#if 0
    NSTrackingArea *trackingArea = nil;
    NSInteger eventNumber, clickCount, buttonNumber;
#endif








|







47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
 */

@implementation TKApplication(TKMouseEvent)
- (NSEvent *) tkProcessMouseEvent: (NSEvent *) theEvent
{
    NSWindow *eventWindow = [theEvent window];
    NSEventType eventType = [theEvent type];
    TkWindow *winPtr = NULL, *grabWinPtr;
    Tk_Window tkwin;
    NSPoint local, global;
#if 0
    NSTrackingArea *trackingArea = nil;
    NSInteger eventNumber, clickCount, buttonNumber;
#endif

Changes to jni/sdl2tk/macosx/tkMacOSXPrivate.h.
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
@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

@interface TKContentView(TKKeyEvent)
- (void) deleteWorkingText;
@end







<
<

<







337
338
339
340
341
342
343


344

345
346
347
348
349
350
351
@end

VISIBILITY_HIDDEN
@interface TKContentView : NSView <NSTextInput>
{
@private
    NSString *privateWorkingText;


    Bool _needsRedisplay;

}
@property Bool needsRedisplay;
@end

@interface TKContentView(TKKeyEvent)
- (void) deleteWorkingText;
@end
Changes to jni/sdl2tk/macosx/tkMacOSXScrlbr.c.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

29
30
31
32
33
34
35
/*
 * tkMacOSXScrollbar.c --
 *
 *	This file implements the Macintosh specific portion of the scrollbar
 *	widget.
 *
 * Copyright (c) 1996 by Sun Microsystems, Inc.
 * Copyright 2001-2009, Apple Inc.
 * Copyright (c) 2006-2009 Daniel A. Steffen <das@users.sourceforge.net>
 * Copyright (c) 2015 Kevin Walzer/WordTech Commununications LLC.
 * Copyright (c) 2018 Marc Culler
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"
#include "tkScrollbar.h"
#include "tkMacOSXPrivate.h"

#define MIN_SCROLLBAR_VALUE		0

/*
 * Minimum slider length, in pixels (designed to make sure that the slider is
 * always easy to grab with the mouse).
 */

#define MIN_SLIDER_LENGTH	5


/*
 * Borrowed from ttkMacOSXTheme.c to provide appropriate scaling.
 */

#ifdef __LP64__
#define RangeToFactor(maximum)	(((double) (INT_MAX >> 1)) / (maximum))










|









<
<





|
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20


21
22
23
24
25
26
27
28
29
30
31
32
33
34
/*
 * tkMacOSXScrollbar.c --
 *
 *	This file implements the Macintosh specific portion of the scrollbar
 *	widget.
 *
 * Copyright (c) 1996 by Sun Microsystems, Inc.
 * Copyright 2001-2009, Apple Inc.
 * Copyright (c) 2006-2009 Daniel A. Steffen <das@users.sourceforge.net>
 * Copyright (c) 2015 Kevin Walzer/WordTech Commununications LLC.
 * Copyright (c) 2018-2019 Marc Culler
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"
#include "tkScrollbar.h"
#include "tkMacOSXPrivate.h"



/*
 * Minimum slider length, in pixels (designed to make sure that the slider is
 * always easy to grab with the mouse).
 */

#define MIN_SLIDER_LENGTH	18
#define MIN_GAP			4

/*
 * Borrowed from ttkMacOSXTheme.c to provide appropriate scaling.
 */

#ifdef __LP64__
#define RangeToFactor(maximum)	(((double) (INT_MAX >> 1)) / (maximum))
84
85
86
87
88
89
90
91

92
93
94
95
96
97
98
typedef struct ScrollbarMetrics {
    SInt32 width, minThumbHeight;
    int minHeight, topArrowHeight, bottomArrowHeight;
    NSControlSize controlSize;
} ScrollbarMetrics;

static ScrollbarMetrics metrics = {
    15, 54, 26, 14, 14, kControlSizeNormal /* kThemeScrollBarMedium */

};

/*
 * Declarations of static functions defined later in this file:
 */

static void		ScrollbarEventProc(ClientData clientData,







|
>







83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
typedef struct ScrollbarMetrics {
    SInt32 width, minThumbHeight;
    int minHeight, topArrowHeight, bottomArrowHeight;
    NSControlSize controlSize;
} ScrollbarMetrics;

static ScrollbarMetrics metrics = {
    /* kThemeScrollBarMedium */
    15, MIN_SLIDER_LENGTH, 26, 14, 14, kControlSizeNormal
};

/*
 * Declarations of static functions defined later in this file:
 */

static void		ScrollbarEventProc(ClientData clientData,
156
157
158
159
160
161
162










































































163
164
165
166
167
168
169
 *
 * Side effects:
 *	Draws a scrollbar on the screen.
 *
 *--------------------------------------------------------------
 */











































































void
TkpDisplayScrollbar(
    ClientData clientData)	/* Information about window. */
{
    TkScrollbar *scrollPtr = clientData;
    MacScrollbar *msPtr = (MacScrollbar *) scrollPtr;
    Tk_Window tkwin = scrollPtr->tkwin;







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
 *
 * Side effects:
 *	Draws a scrollbar on the screen.
 *
 *--------------------------------------------------------------
 */

#if MAC_OS_X_VERSION_MAX_ALLOWED > 1080

/*
 * This stand-alone drawing function is used on macOS 10.9 and newer because
 * the HIToolbox does not draw the scrollbar thumb at the expected size on
 * those systems.  The thumb is drawn too large, causing a mouse click on the
 * thumb to be interpreted as a mouse click in the trough.
 */

static void drawMacScrollbar(
    TkScrollbar *scrollPtr,
    MacScrollbar *msPtr,
    CGContextRef context)
{
    MacDrawable *macWin = (MacDrawable *) Tk_WindowId(scrollPtr->tkwin);
    NSView *view = TkMacOSXDrawableView(macWin);
    CGPathRef path;
    CGPoint inner[2], outer[2], thumbOrigin;
    CGSize thumbSize;
    CGRect troughBounds = msPtr->info.bounds;
    troughBounds.origin.y = [view bounds].size.height -
	(troughBounds.origin.y + troughBounds.size.height);
    if (scrollPtr->vertical) {
	thumbOrigin.x = troughBounds.origin.x + MIN_GAP;
	thumbOrigin.y = troughBounds.origin.y + scrollPtr->sliderFirst;
	thumbSize.width = troughBounds.size.width - 2*MIN_GAP + 1;
	thumbSize.height = scrollPtr->sliderLast - scrollPtr->sliderFirst;
	inner[0] = troughBounds.origin;
	inner[1] = CGPointMake(inner[0].x,
			       inner[0].y + troughBounds.size.height);
	outer[0] = CGPointMake(inner[0].x + troughBounds.size.width - 1,
			       inner[0].y);
	outer[1] = CGPointMake(outer[0].x, inner[1].y);
    } else {
	thumbOrigin.x = troughBounds.origin.x + scrollPtr->sliderFirst;
	thumbOrigin.y = troughBounds.origin.y + MIN_GAP;
	thumbSize.width = scrollPtr->sliderLast - scrollPtr->sliderFirst;
	thumbSize.height = troughBounds.size.height - 2*MIN_GAP + 1;
	inner[0] = troughBounds.origin;
	inner[1] = CGPointMake(inner[0].x + troughBounds.size.width,
			       inner[0].y + 1);
	outer[0] = CGPointMake(inner[0].x,
			       inner[0].y + troughBounds.size.height);
	outer[1] = CGPointMake(inner[1].x, outer[0].y);
    }
    CGContextSetShouldAntialias(context, false);
    CGContextSetGrayFillColor(context, 250.0 / 255, 1.0);
    CGContextFillRect(context, troughBounds);
    CGContextSetGrayStrokeColor(context, 232.0 / 255, 1.0);
    CGContextStrokeLineSegments(context, inner, 2);
    CGContextSetGrayStrokeColor(context, 238.0 / 255, 1.0);
    CGContextStrokeLineSegments(context, outer, 2);

    /*
     * Do not display the thumb unless scrolling is possible.
     */
    
    if (scrollPtr->firstFraction > 0.0 || scrollPtr->lastFraction < 1.0) {
	CGRect thumbBounds = {thumbOrigin, thumbSize};
	path = CGPathCreateWithRoundedRect(thumbBounds, 4, 4, NULL);
	CGContextBeginPath(context);
	CGContextAddPath(context, path);
	if (msPtr->info.trackInfo.scrollbar.pressState != 0) {
	    CGContextSetGrayFillColor(context, 133.0 / 255, 1.0);
	} else {
	    CGContextSetGrayFillColor(context, 200.0 / 255, 1.0);
	}
	CGContextSetShouldAntialias(context, true);
	CGContextFillPath(context);
	CFRelease(path);
    }
}
#endif
	       
void
TkpDisplayScrollbar(
    ClientData clientData)	/* Information about window. */
{
    TkScrollbar *scrollPtr = clientData;
    MacScrollbar *msPtr = (MacScrollbar *) scrollPtr;
    Tk_Window tkwin = scrollPtr->tkwin;
181
182
183
184
185
186
187




188
189
190
191
192
193
194

    if ((view == NULL)
	    || (macWin->flags & TK_DO_NOT_DRAW)
	    || !TkMacOSXSetupDrawingContext((Drawable) macWin, NULL, 1, &dc)) {
	return;
    }





    CGFloat viewHeight = [view bounds].size.height;
    CGAffineTransform t = {
	.a = 1, .b = 0,
	.c = 0, .d = -1,
	.tx = 0, .ty = viewHeight
    };








>
>
>
>







255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272

    if ((view == NULL)
	    || (macWin->flags & TK_DO_NOT_DRAW)
	    || !TkMacOSXSetupDrawingContext((Drawable) macWin, NULL, 1, &dc)) {
	return;
    }

    /*
     * Transform NSView coordinates to CoreGraphics coordinates.
     */

    CGFloat viewHeight = [view bounds].size.height;
    CGAffineTransform t = {
	.a = 1, .b = 0,
	.c = 0, .d = -1,
	.tx = 0, .ty = viewHeight
    };

225
226
227
228
229
230
231
232
233
234
235


236



237



238

239
240
241
242
243
244
245
     * Update values and then draw the native scrollbar over the rectangle.
     */

    UpdateControlValues(scrollPtr);

    if (SNOW_LEOPARD_STYLE) {
	HIThemeDrawTrack(&msPtr->info, 0, dc.context,
		kHIThemeOrientationInverted);
    } else {
	HIThemeDrawTrack(&msPtr->info, 0, dc.context,
		kHIThemeOrientationNormal);


    }



    TkMacOSXRestoreDrawingContext(&dc);





    scrollPtr->flags &= ~REDRAW_PENDING;
}

/*
 *----------------------------------------------------------------------
 *
 * TkpComputeScrollbarGeometry --







|
|

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







303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
     * Update values and then draw the native scrollbar over the rectangle.
     */

    UpdateControlValues(scrollPtr);

    if (SNOW_LEOPARD_STYLE) {
	HIThemeDrawTrack(&msPtr->info, 0, dc.context,
			 kHIThemeOrientationInverted);
    } else if ([NSApp macMinorVersion] <= 8) {
	HIThemeDrawTrack(&msPtr->info, 0, dc.context,
			 kHIThemeOrientationNormal);
    } else {
#if MAC_OS_X_VERSION_MAX_ALLOWED > 1080

	/*
	 * Switch back to NSView coordinates and draw a modern scrollbar.
	 */
	
	CGContextConcatCTM(dc.context, t);
	drawMacScrollbar(scrollPtr, msPtr, dc.context);
#endif
    }
    TkMacOSXRestoreDrawingContext(&dc);
    scrollPtr->flags &= ~REDRAW_PENDING;
}

/*
 *----------------------------------------------------------------------
 *
 * TkpComputeScrollbarGeometry --
293
294
295
296
297
298
299
300
301
302

303
304








305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
    if (fieldLength < 0) {
	fieldLength = 0;
    }
    scrollPtr->sliderFirst = fieldLength*scrollPtr->firstFraction;
    scrollPtr->sliderLast = fieldLength*scrollPtr->lastFraction;

    /*
     * Adjust the slider so that some piece of it is always displayed in the
     * scrollbar and so that it has at least a minimal width (so it can be
     * grabbed with the mouse).

     */









    if (scrollPtr->sliderFirst > fieldLength - MIN_SLIDER_LENGTH) {
	scrollPtr->sliderFirst = fieldLength - MIN_SLIDER_LENGTH;
    }
    if (scrollPtr->sliderFirst < 0) {
	scrollPtr->sliderFirst = 0;
    }
    if (scrollPtr->sliderLast < scrollPtr->sliderFirst + MIN_SLIDER_LENGTH) {
	scrollPtr->sliderLast = scrollPtr->sliderFirst + MIN_SLIDER_LENGTH;
    }
    if (scrollPtr->sliderLast > fieldLength) {
	scrollPtr->sliderLast = fieldLength;
    }
    scrollPtr->sliderFirst += -scrollPtr->arrowLength + scrollPtr->inset;
    scrollPtr->sliderLast += scrollPtr->inset;

    /*
     * Register the desired geometry for the window. Leave enough space for the
     * two arrows, if there are any arrows, plus a minimum-size slider, plus
     * border around the whole window, if any. Then arrange for the window to







<
|
<
>


>
>
>
>
>
>
>
>



<
<
<



<
<
<







380
381
382
383
384
385
386

387

388
389
390
391
392
393
394
395
396
397
398
399
400
401



402
403
404



405
406
407
408
409
410
411
    if (fieldLength < 0) {
	fieldLength = 0;
    }
    scrollPtr->sliderFirst = fieldLength*scrollPtr->firstFraction;
    scrollPtr->sliderLast = fieldLength*scrollPtr->lastFraction;

    /*

     * Adjust the slider so that it has at least a minimal size and so there

     * is a small gap on either end which can be used to scroll by one page.
     */

    if (scrollPtr->sliderFirst < MIN_GAP) {
	scrollPtr->sliderFirst = MIN_GAP;
	scrollPtr->sliderLast += MIN_GAP;
    }
    if (scrollPtr->sliderLast > fieldLength - MIN_GAP) {
	scrollPtr->sliderLast = fieldLength - MIN_GAP;
	scrollPtr->sliderFirst -= MIN_GAP;
    }
    if (scrollPtr->sliderFirst > fieldLength - MIN_SLIDER_LENGTH) {
	scrollPtr->sliderFirst = fieldLength - MIN_SLIDER_LENGTH;
    }



    if (scrollPtr->sliderLast < scrollPtr->sliderFirst + MIN_SLIDER_LENGTH) {
	scrollPtr->sliderLast = scrollPtr->sliderFirst + MIN_SLIDER_LENGTH;
    }



    scrollPtr->sliderFirst += -scrollPtr->arrowLength + scrollPtr->inset;
    scrollPtr->sliderLast += scrollPtr->inset;

    /*
     * Register the desired geometry for the window. Leave enough space for the
     * two arrows, if there are any arrows, plus a minimum-size slider, plus
     * border around the whole window, if any. Then arrange for the window to
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
    frame = NSInsetRect(frame, scrollPtr->inset, scrollPtr->inset);
    frame.origin.y = viewHeight - (frame.origin.y + frame.size.height);

    contrlRect = NSRectToCGRect(frame);
    msPtr->info.bounds = contrlRect;

    width = contrlRect.size.width;
    height = contrlRect.size.height;

    /*
     * Ensure we set scrollbar control bounds only once all size adjustments
     * have been computed.
     */

    msPtr->info.bounds = contrlRect;







|







595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
    frame = NSInsetRect(frame, scrollPtr->inset, scrollPtr->inset);
    frame.origin.y = viewHeight - (frame.origin.y + frame.size.height);

    contrlRect = NSRectToCGRect(frame);
    msPtr->info.bounds = contrlRect;

    width = contrlRect.size.width;
    height = contrlRect.size.height - scrollPtr->arrowLength;

    /*
     * Ensure we set scrollbar control bounds only once all size adjustments
     * have been computed.
     */

    msPtr->info.bounds = contrlRect;
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
     * Macintosh thumb. The Aqua scroll control works as follows. The
     * scrollbar's value is the position of the left (or top) side of the view
     * area in the content area being scrolled. The maximum value of the
     * control is therefore the dimension of the content area less the size of
     * the view area.
     */

    double maximum = 100, factor = RangeToFactor(maximum);

    dViewSize = (scrollPtr->lastFraction - scrollPtr->firstFraction) * factor;
    msPtr->info.max = MIN_SCROLLBAR_VALUE + factor - dViewSize;
    msPtr->info.trackInfo.scrollbar.viewsize = dViewSize;
    if (scrollPtr->vertical) {
	if (SNOW_LEOPARD_STYLE) {
	    msPtr->info.value = factor * scrollPtr->firstFraction;
	} else {
	    msPtr->info.value = msPtr->info.max -
		    factor * scrollPtr->firstFraction;
	}
    } else {
	msPtr->info.value = MIN_SCROLLBAR_VALUE +
		factor * scrollPtr->firstFraction;
    }

    if ((scrollPtr->firstFraction <= 0.0 && scrollPtr->lastFraction >= 1.0)
	    || height <= metrics.minHeight) {
    	msPtr->info.enableState = kThemeTrackHideTrack;
    } else {
        msPtr->info.enableState = kThemeTrackActive;







|
<

|









<
|







619
620
621
622
623
624
625
626

627
628
629
630
631
632
633
634
635
636
637

638
639
640
641
642
643
644
645
     * Macintosh thumb. The Aqua scroll control works as follows. The
     * scrollbar's value is the position of the left (or top) side of the view
     * area in the content area being scrolled. The maximum value of the
     * control is therefore the dimension of the content area less the size of
     * the view area.
     */

    double factor = RangeToFactor(100.0);

    dViewSize = (scrollPtr->lastFraction - scrollPtr->firstFraction) * factor;
    msPtr->info.max = factor - dViewSize;
    msPtr->info.trackInfo.scrollbar.viewsize = dViewSize;
    if (scrollPtr->vertical) {
	if (SNOW_LEOPARD_STYLE) {
	    msPtr->info.value = factor * scrollPtr->firstFraction;
	} else {
	    msPtr->info.value = msPtr->info.max -
		    factor * scrollPtr->firstFraction;
	}
    } else {

	msPtr->info.value = factor * scrollPtr->firstFraction;
    }

    if ((scrollPtr->firstFraction <= 0.0 && scrollPtr->lastFraction >= 1.0)
	    || height <= metrics.minHeight) {
    	msPtr->info.enableState = kThemeTrackHideTrack;
    } else {
        msPtr->info.enableState = kThemeTrackActive;
612
613
614
615
616
617
618

619
620
621
622
623
624
625
	    msPtr->info.trackInfo.scrollbar.pressState = kThemeThumbPressed;
	    break;
	case BOTTOM_GAP:
	    msPtr->info.trackInfo.scrollbar.pressState =
		    kThemeBottomTrackPressed;
	    break;
	case TOP_ARROW:

	    /*
	     * This looks wrong and the docs say it is wrong but it works.
	     */

	    msPtr->info.trackInfo.scrollbar.pressState =
		    kThemeTopInsideArrowPressed;
	    break;







>







698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
	    msPtr->info.trackInfo.scrollbar.pressState = kThemeThumbPressed;
	    break;
	case BOTTOM_GAP:
	    msPtr->info.trackInfo.scrollbar.pressState =
		    kThemeBottomTrackPressed;
	    break;
	case TOP_ARROW:

	    /*
	     * This looks wrong and the docs say it is wrong but it works.
	     */

	    msPtr->info.trackInfo.scrollbar.pressState =
		    kThemeTopInsideArrowPressed;
	    break;
643
644
645
646
647
648
649

650
651
652
653
654
655
656
    }
    if (eventPtr->type == LeaveNotify) {
	msPtr->mouseOver = false;
	if (!msPtr->buttonDown) {
	    msPtr->info.trackInfo.scrollbar.pressState = 0;
	}
    }

    return TCL_OK;
}

/*
 *--------------------------------------------------------------
 *
 * ScrollbarEventProc --







>







730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
    }
    if (eventPtr->type == LeaveNotify) {
	msPtr->mouseOver = false;
	if (!msPtr->buttonDown) {
	    msPtr->info.trackInfo.scrollbar.pressState = 0;
	}
    }
    TkScrollbarEventuallyRedraw(scrollPtr);
    return TCL_OK;
}

/*
 *--------------------------------------------------------------
 *
 * ScrollbarEventProc --
Changes to jni/sdl2tk/macosx/tkMacOSXServices.c.
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
 * 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.
     */







|







116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
 * that must be defined in info.plist.
 */

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

    /*
     * Get string from private pasteboard, write to general pasteboard to make
     * available to Tcl service.
     */
Changes to jni/sdl2tk/macosx/ttkMacOSXTheme.c.
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064

1065
1066
1067
1068
1069
1070
1071
						count:4];
    CGFloat x = bounds.origin.x, y = bounds.origin.y;
    CGFloat w = bounds.size.width, h = bounds.size.height;
    CGPoint topPart[4] = {
	{x, y + h}, {x, y + 1}, {x + w - 1, y + 1}, {x + w - 1, y + h}
    };
    CGPoint bottom[2] = {{x, y + h}, {x + w, y + h}};
    CGRect outerRect = CGRectInset(bounds, -3, -3);

    CGContextSaveGState(context);
    CGContextSetShouldAntialias(context, false);
    CGContextBeginPath(context);
    strokeColor = [NSColor colorWithColorSpace: deviceRGB
				    components: darkFocusRingTop
					 count: 4];
    CGContextSetStrokeColorWithColor(context, CGCOLOR(strokeColor));
    CGContextAddLines(context, topPart, 4);
    CGContextStrokePath(context);
    strokeColor = [NSColor colorWithColorSpace: deviceRGB
				    components: darkFocusRingBottom
					 count: 4];
    CGContextSetStrokeColorWithColor(context, CGCOLOR(strokeColor));
    CGContextAddLines(context, bottom, 2);
    CGContextStrokePath(context);
    CGContextSetShouldAntialias(context, true);
    CGContextSetFillColorWithColor(context, CGCOLOR(fillColor));
    CGPathRef path = CGPathCreateWithRoundedRect(outerRect, 4, 4, NULL);

    CGContextBeginPath(context);
    CGContextAddPath(context, path);
    CGContextAddRect(context, bounds);
    CGContextEOFillPath(context);
    CGContextRestoreGState(context);
}
/*----------------------------------------------------------------------







<


















|
>







1038
1039
1040
1041
1042
1043
1044

1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
						count:4];
    CGFloat x = bounds.origin.x, y = bounds.origin.y;
    CGFloat w = bounds.size.width, h = bounds.size.height;
    CGPoint topPart[4] = {
	{x, y + h}, {x, y + 1}, {x + w - 1, y + 1}, {x + w - 1, y + h}
    };
    CGPoint bottom[2] = {{x, y + h}, {x + w, y + h}};


    CGContextSaveGState(context);
    CGContextSetShouldAntialias(context, false);
    CGContextBeginPath(context);
    strokeColor = [NSColor colorWithColorSpace: deviceRGB
				    components: darkFocusRingTop
					 count: 4];
    CGContextSetStrokeColorWithColor(context, CGCOLOR(strokeColor));
    CGContextAddLines(context, topPart, 4);
    CGContextStrokePath(context);
    strokeColor = [NSColor colorWithColorSpace: deviceRGB
				    components: darkFocusRingBottom
					 count: 4];
    CGContextSetStrokeColorWithColor(context, CGCOLOR(strokeColor));
    CGContextAddLines(context, bottom, 2);
    CGContextStrokePath(context);
    CGContextSetShouldAntialias(context, true);
    CGContextSetFillColorWithColor(context, CGCOLOR(fillColor));
    CGPathRef path = CGPathCreateWithRoundedRect(CGRectInset(bounds, -3, -3),
						 4, 4, NULL);
    CGContextBeginPath(context);
    CGContextAddPath(context, path);
    CGContextAddRect(context, bounds);
    CGContextEOFillPath(context);
    CGContextRestoreGState(context);
}
/*----------------------------------------------------------------------
1087
1088
1089
1090
1091
1092
1093

1094
1095
1096
1097
1098
1099
1100
    CGFloat x = bounds.origin.x, y = bounds.origin.y;
    CGFloat w = bounds.size.width, h = bounds.size.height;
    CGPoint topPart[4] = {
	{x, y + h - 1}, {x, y + 1}, {x + w, y + 1}, {x + w, y + h - 1}
    };
    CGPoint bottom[2] = {{x, y + h}, {x + w, y + h}};
    CGPoint accent[2] = {{x, y + 1}, {x + w, y + 1}};

    switch (kind) {
    case kHIThemeFrameTextFieldSquare:
	CGContextSaveGState(context);
	CGContextSetShouldAntialias(context, false);
	CGContextBeginPath(context);
	stroke = [NSColor colorWithColorSpace: deviceRGB
	    components: darkFrameTop







>







1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
    CGFloat x = bounds.origin.x, y = bounds.origin.y;
    CGFloat w = bounds.size.width, h = bounds.size.height;
    CGPoint topPart[4] = {
	{x, y + h - 1}, {x, y + 1}, {x + w, y + 1}, {x + w, y + h - 1}
    };
    CGPoint bottom[2] = {{x, y + h}, {x + w, y + h}};
    CGPoint accent[2] = {{x, y + 1}, {x + w, y + 1}};

    switch (kind) {
    case kHIThemeFrameTextFieldSquare:
	CGContextSaveGState(context);
	CGContextSetShouldAntialias(context, false);
	CGContextBeginPath(context);
	stroke = [NSColor colorWithColorSpace: deviceRGB
	    components: darkFrameTop
2341
2342
2343
2344
2345
2346
2347

2348





2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
    int *minHeight,
    Ttk_Padding *paddingPtr)
{
    ScrollbarElement *scrollbar = elementRecord;
    int orientation = TTK_ORIENT_HORIZONTAL;

    Ttk_GetOrientFromObj(NULL, scrollbar->orientObj, &orientation);

    *minHeight = *minWidth = 8;





}

static void ThumbElementDraw(
    void *clientData,
    void *elementRecord,
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    Ttk_State state)
{
    ScrollbarElement *scrollbar = elementRecord;
    int orientation = TTK_ORIENT_HORIZONTAL;

    Ttk_GetOrientFromObj(NULL, scrollbar->orientObj, &orientation);

    /*
     * In order to make ttk scrollbars work correctly it is necessary to be
     * able to display the thumb element at the size and location which the ttk
     * scrollbar widget requests.  The algorithm that HIToolbox uses to
     * determine the thumb geometry from the input values of min, max, value
     * and viewSize is, of course, undocumented.  And this turns out to be a
     * hard reverse engineering problem.  A seemingly natural algorithm is
     * implemented below, but it does not correctly compute the same thumb
     * geometry as HITools (which also apparently does not agree with
     * NSScrollbar).  This code uses that algorithm for older OS versions,
     * because using HITools also handles drawing the buttons and 3D thumb used
     * on those systems.  The incorrect geometry is annoying but not completely
     * unusable.  For newer systems the cleanest approach is to just draw the
     * thumb directly.
     */

    if ([NSApp macMinorVersion] > 8) {
	CGRect thumbBounds = BoxToRect(d, b);
	NSColorSpace *deviceRGB = [NSColorSpace deviceRGBColorSpace];
	NSColor *thumbColor;
	CGFloat *rgba;







>
|
>
>
>
>
>




















<
|
<
<
|

<
|
|







2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375

2376


2377
2378

2379
2380
2381
2382
2383
2384
2385
2386
2387
    int *minHeight,
    Ttk_Padding *paddingPtr)
{
    ScrollbarElement *scrollbar = elementRecord;
    int orientation = TTK_ORIENT_HORIZONTAL;

    Ttk_GetOrientFromObj(NULL, scrollbar->orientObj, &orientation);
    if (orientation == TTK_ORIENT_VERTICAL) {
	*minHeight = 18;
	*minWidth = 8;
    } else {
	*minHeight = 8;
	*minWidth = 18;
    }	
}

static void ThumbElementDraw(
    void *clientData,
    void *elementRecord,
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    Ttk_State state)
{
    ScrollbarElement *scrollbar = elementRecord;
    int orientation = TTK_ORIENT_HORIZONTAL;

    Ttk_GetOrientFromObj(NULL, scrollbar->orientObj, &orientation);

    /*
     * In order to make ttk scrollbars work correctly it is necessary to be
     * able to display the thumb element at the size and location which the ttk
     * scrollbar widget requests.  The algorithm that HIToolbox uses to
     * determine the thumb geometry from the input values of min, max, value

     * and viewSize is undocumented.  A seemingly natural algorithm is


     * implemented below.  This code uses that algorithm for older OS versions,
     * because using HITools also handles drawing the buttons and 3D thumb used

     * on those systems.  For newer systems the cleanest approach is to just
     * draw the thumb directly.
     */

    if ([NSApp macMinorVersion] > 8) {
	CGRect thumbBounds = BoxToRect(d, b);
	NSColorSpace *deviceRGB = [NSColorSpace deviceRGBColorSpace];
	NSColor *thumbColor;
	CGFloat *rgba;
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435

2436
2437

2438
2439





2440
2441
2442
2443
2444
2445
2446
2447
	thumbColor = [NSColor colorWithColorSpace: deviceRGB
	    components: rgba
	    count: 4];
	BEGIN_DRAWING(d)
	SolidFillRoundedRectangle(dc.context, thumbBounds, 4, thumbColor);
	END_DRAWING
    } else {
	double thumbSize, trackSize, visibleSize, viewSize;
	MacDrawable *macWin = (MacDrawable *) Tk_WindowId(tkwin);
	CGRect troughBounds = {{macWin->xOff, macWin->yOff},
			       {Tk_Width(tkwin), Tk_Height(tkwin)}};

        /*
         * The info struct has integer fields, which will be converted to
         * floats in the drawing routine.  All of values provided in the info
         * struct, namely min, max, value, and viewSize are only defined up to
         * an arbitrary scale factor.  To avoid roundoff error we scale so
         * that the viewSize is a large float which is smaller than the
         * largest int.
         */

	viewSize = RangeToFactor(100.0);
	HIThemeTrackDrawInfo info = {
	    .version = 0,
	    .bounds = troughBounds,
	    .min = 0,
	    .attributes = kThemeTrackShowThumb |
		kThemeTrackThumbRgnIsNotGhost,
	    .enableState = kThemeTrackActive
	};
	info.trackInfo.scrollbar.viewsize = viewSize * .8;
	if (orientation == TTK_ORIENT_HORIZONTAL) {
	    trackSize = troughBounds.size.width;
	    thumbSize = b.width;
	    visibleSize = (thumbSize / trackSize) * viewSize;
	    info.max = viewSize - visibleSize;
	    info.value = info.max * (b.x / (trackSize - thumbSize));
	} else {

	    thumbSize = b.height;
	    trackSize = troughBounds.size.height;

	    visibleSize = (thumbSize / trackSize) * viewSize;
	    info.max = viewSize - visibleSize;





	    info.value = info.max * (b.y / (trackSize - thumbSize));
	}
	if ((state & TTK_STATE_PRESSED) ||
	    (state & TTK_STATE_HOVER)) {
	    info.trackInfo.scrollbar.pressState = kThemeThumbPressed;
	} else {
	    info.trackInfo.scrollbar.pressState = 0;
	}







|













<








|



|
<
<

>

|
>
|
|
>
>
>
>
>
|







2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421

2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434


2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
	thumbColor = [NSColor colorWithColorSpace: deviceRGB
	    components: rgba
	    count: 4];
	BEGIN_DRAWING(d)
	SolidFillRoundedRectangle(dc.context, thumbBounds, 4, thumbColor);
	END_DRAWING
    } else {
	double thumbSize, trackSize, visibleSize, factor, fraction;
	MacDrawable *macWin = (MacDrawable *) Tk_WindowId(tkwin);
	CGRect troughBounds = {{macWin->xOff, macWin->yOff},
			       {Tk_Width(tkwin), Tk_Height(tkwin)}};

        /*
         * The info struct has integer fields, which will be converted to
         * floats in the drawing routine.  All of values provided in the info
         * struct, namely min, max, value, and viewSize are only defined up to
         * an arbitrary scale factor.  To avoid roundoff error we scale so
         * that the viewSize is a large float which is smaller than the
         * largest int.
         */


	HIThemeTrackDrawInfo info = {
	    .version = 0,
	    .bounds = troughBounds,
	    .min = 0,
	    .attributes = kThemeTrackShowThumb |
		kThemeTrackThumbRgnIsNotGhost,
	    .enableState = kThemeTrackActive
	};
	factor = RangeToFactor(100.0);
	if (orientation == TTK_ORIENT_HORIZONTAL) {
	    trackSize = troughBounds.size.width;
	    thumbSize = b.width;
	    fraction = b.x / trackSize;


	} else {
	    trackSize = troughBounds.size.height;
	    thumbSize = b.height;
	    fraction = b.y / trackSize;
	}
	visibleSize = (thumbSize / trackSize) * factor;
	info.max = factor - visibleSize;
	info.trackInfo.scrollbar.viewsize = visibleSize;
	if ([NSApp macMinorVersion] < 8 ||
	    orientation == TTK_ORIENT_HORIZONTAL) {
	    info.value = factor * fraction;
	} else {
	    info.value = info.max - factor * fraction;
	}
	if ((state & TTK_STATE_PRESSED) ||
	    (state & TTK_STATE_HOVER)) {
	    info.trackInfo.scrollbar.pressState = kThemeThumbPressed;
	} else {
	    info.trackInfo.scrollbar.pressState = 0;
	}
Changes to jni/tcl/generic/tclExecute.c.
9007
9008
9009
9010
9011
9012
9013
9014
9015
9016
9017
9018
9019
9020
9021
		|| (Tcl_WideUInt)w2 >= (1<<28)) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "exponent too large", -1));
	    return GENERAL_ARITHMETIC_ERROR;
	}
	Tcl_TakeBignumFromObj(NULL, valuePtr, &big1);
	mp_init(&bigResult);
	mp_expt_d(&big1, w2, &bigResult);
	mp_clear(&big1);
	BIG_RESULT(&bigResult);
    }

    case INST_ADD:
    case INST_SUB:
    case INST_MULT:







|







9007
9008
9009
9010
9011
9012
9013
9014
9015
9016
9017
9018
9019
9020
9021
		|| (Tcl_WideUInt)w2 >= (1<<28)) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "exponent too large", -1));
	    return GENERAL_ARITHMETIC_ERROR;
	}
	Tcl_TakeBignumFromObj(NULL, valuePtr, &big1);
	mp_init(&bigResult);
	mp_expt_d(&big1, (mp_digit)w2, &bigResult);
	mp_clear(&big1);
	BIG_RESULT(&bigResult);
    }

    case INST_ADD:
    case INST_SUB:
    case INST_MULT:
Changes to jni/tcl/generic/tclHash.c.
835
836
837
838
839
840
841

842
843
844
845
846
847
848
    unsigned int size, allocsize;

    allocsize = size = strlen(string) + 1;
    if (size < sizeof(hPtr->key)) {
	allocsize = sizeof(hPtr->key);
    }
    hPtr = ckalloc(TclOffset(Tcl_HashEntry, key) + allocsize);

    memcpy(hPtr->key.string, string, size);
    hPtr->clientData = 0;
    return hPtr;
}

/*
 *----------------------------------------------------------------------







>







835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
    unsigned int size, allocsize;

    allocsize = size = strlen(string) + 1;
    if (size < sizeof(hPtr->key)) {
	allocsize = sizeof(hPtr->key);
    }
    hPtr = ckalloc(TclOffset(Tcl_HashEntry, key) + allocsize);
    memset(hPtr, 0, sizeof(Tcl_HashEntry) + allocsize - sizeof(hPtr->key));
    memcpy(hPtr->key.string, string, size);
    hPtr->clientData = 0;
    return hPtr;
}

/*
 *----------------------------------------------------------------------
Added misc/EuroTcl2019.odp.

cannot compute difference between binary files

Added misc/EuroTcl2019.pdf.

cannot compute difference between binary files

Changes to undroid/build-undroidwish-macosx.sh.
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
  cp -p undroidwish ${APP}/Contents/MacOS
  cp -p sdl2tk/sdl/undroidwish.icns sdl2tk/sdl/undroidwish.tiff \
    ${APP}/Contents/Resources
  cp -p sdl2tk/sdl/undroidwish-Info.plist ${APP}/Contents/Info.plist
  (
    cd ${APPDIR}
    # provide some symlinked apps
    for f in tksqlite bugz zint dungfork vncviewer tkmc helpviewer stardom TSB ; do
      mkdir -p ${f}.app/Contents
      ln -sf ../../undroidwish.app/Contents/MacOS ${f}.app/Contents
      ln -sf ../../undroidwish.app/Contents/Resources ${f}.app/Contents
      ( cd undroidwish.app/Contents/MacOS ; ln -s undroidwish $f )
      cp undroidwish.app/Contents/Info.plist ${f}.app/Contents
      perl -pi -e 's@<string>undroidawish</string>@<string>'$f'</string>@g' \
        ${f}.app/Contents/Info.plist
    done
    if test -d ${AWDIR}/assets/tkchat* ; then
      mkdir -p tkchat.app/Contents
      ln -sf ../../undroidwish.app/Contents/MacOS tkchat.app/Contents
      ln -sf ../../undroidwish.app/Contents/Resources tkchat.app/Contents
      ( cd undroidwish.app/Contents/MacOS ; ln -s undroidwish tkchat )







|





|







1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
  cp -p undroidwish ${APP}/Contents/MacOS
  cp -p sdl2tk/sdl/undroidwish.icns sdl2tk/sdl/undroidwish.tiff \
    ${APP}/Contents/Resources
  cp -p sdl2tk/sdl/undroidwish-Info.plist ${APP}/Contents/Info.plist
  (
    cd ${APPDIR}
    # provide some symlinked apps
    for f in tksqlite bugz zint dungfork vncviewer tkmc helpviewer stardom ; do
      mkdir -p ${f}.app/Contents
      ln -sf ../../undroidwish.app/Contents/MacOS ${f}.app/Contents
      ln -sf ../../undroidwish.app/Contents/Resources ${f}.app/Contents
      ( cd undroidwish.app/Contents/MacOS ; ln -s undroidwish $f )
      cp undroidwish.app/Contents/Info.plist ${f}.app/Contents
      perl -pi -e 's@<string>undroidwish</string>@<string>'$f'</string>@g' \
        ${f}.app/Contents/Info.plist
    done
    if test -d ${AWDIR}/assets/tkchat* ; then
      mkdir -p tkchat.app/Contents
      ln -sf ../../undroidwish.app/Contents/MacOS tkchat.app/Contents
      ln -sf ../../undroidwish.app/Contents/Resources tkchat.app/Contents
      ( cd undroidwish.app/Contents/MacOS ; ln -s undroidwish tkchat )
Changes to undroid/tsb/tsb.tcl.
521
522
523
524
525
526
527





528
529
530
531
532
533
534
535
536
537
	}
	return $all
    }

    proc canvascmd {c cmd args} {
	variable C
	set ret ""





	switch -glob -- $cmd {
	    cr* {
		# create
		set args [lassign $args type]
		set id [incr C($c,id)]
		set coords {}
		set count 0
		foreach arg $args {
		    if {[string is double $arg]} {
			lappend coords $arg







>
>
>
>
>

<
|







521
522
523
524
525
526
527
528
529
530
531
532
533

534
535
536
537
538
539
540
541
	}
	return $all
    }

    proc canvascmd {c cmd args} {
	variable C
	set ret ""
	if {![catch {tcl::prefix match {
	    create bbox cget raise lower destroy delete coords find svg
	} ncmd}]} {
	    set cmd $ncmd
	}
	switch -glob -- $cmd {

	    create {
		set args [lassign $args type]
		set id [incr C($c,id)]
		set coords {}
		set count 0
		foreach arg $args {
		    if {[string is double $arg]} {
			lappend coords $arg
548
549
550
551
552
553
554
555
556
557
558
559
560





561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
			set opt -tags
		    }
		    dict set C($c,$id) $opt $val
		}
		lappend C($c,dlist) $id
		set ret $id
	    }
	    bb* {
		# bbox, assumes measuring text item with "M"
		set ret {0 0 12 16}
	    }
	    cg* {
		# cget





		switch -glob -- [lindex $args 0] {
		    -bd - -bo* {
			set ret 0
		    }
		    -wi* {
			set ret $C($c,width)
		    }
		    -he* {
			set ret $C($c,height)
		    }
		}
	    }
	    ra* {
		# raise
		lassign $args tags
		set all $C($c,dlist)
		foreach t [tagfind $c $tags] {
		    set n [lsearch -exact $all $t]
		    if {$n >= 0} {
			set all [lreplace $all $n $n]
			lappend all $t
		    }
		}
		set C($c,dlist) $all
	    }
	    lo* {
		# lower
		lassign $args tags
		set all $C($c,dlist)
		foreach t [tagfind $c $tags] {
		    set n [lsearch -exact $all $t]
		    if {$n >= 0} {
			set all [lreplace $all $n $n]
			set all [linsert $all 0 $t]
		    }
		}
		set C($c,dlist) $all
	    }
	    des* {
		# destroy
		set cmd $C($c,cmd)
		foreach name [array names C $c,*] {
		    unset C($name)
		}
		rename "::$cmd" {}
	    }
	    de* {
		# delete
		lassign $args tags
		set all $C($c,dlist)
		foreach t [tagfind $c $tags] {
		    set n [lsearch -exact $all $t]
		    if {$n >= 0} {
			set all [lreplace $all $n $n]
			unset C($c,$t)
		    }
		}
		set C($c,dlist) $all
	    }
	    coo* {
		# coords
		set coords [lassign $args id]
		if {![info exists C($c,$id)]} {
		    foreach item $C($c,dlist) {
			set t [dict get $C($c,$item) -tags]
			if {$id in $t} {
			    if {[llength $coords]} {
				dict set C($c,$item) -coords $coords
			    } else {
				set ret [dict get $C($c,$item) -coords]
			    }
			}
		    }
		} elseif {[llength $coords]} {
		    dict set C($c,$id) -coords $coords
		} else {
		    set ret [dict get $C($c,$id) -coords]
		}
	    }
	    fi* {
		# find ?withtag?
		set args [lassign $args tags]
		if {$tags eq "withtag"} {
		    lassign $args tags
		}
		set ret [tagfind $c $tags]
	    }
	    sv* {
		# svg
		set vx ""
		set vy ""
		set vw ""
		set vh ""
		lassign $args vx vy vw vh
		package require can2svg
		set xml "<?xml version='1.0'?>\n"







|
|


<
|
>
>
>
>
>
|
|


|


|




<
|











<
|











<
|






<
|











<
|


















|







<
|







552
553
554
555
556
557
558
559
560
561
562

563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580

581
582
583
584
585
586
587
588
589
590
591
592

593
594
595
596
597
598
599
600
601
602
603
604

605
606
607
608
609
610
611

612
613
614
615
616
617
618
619
620
621
622
623

624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650

651
652
653
654
655
656
657
658
			set opt -tags
		    }
		    dict set C($c,$id) $opt $val
		}
		lappend C($c,dlist) $id
		set ret $id
	    }
	    bbox {
		# assumes measuring text item with "M"
		set ret {0 0 12 16}
	    }

	    cget {
		if {[catch {tcl::prefix match {
		    -bd -borderwidth -width -height
		} [lindex $args 0]} opt]} {
		    set opt [lindex $args 0]
		}
		switch -glob -- $opt {
		    -bd - -borderwidth {
			set ret 0
		    }
		    -width {
			set ret $C($c,width)
		    }
		    -height {
			set ret $C($c,height)
		    }
		}
	    }

	    raise {
		lassign $args tags
		set all $C($c,dlist)
		foreach t [tagfind $c $tags] {
		    set n [lsearch -exact $all $t]
		    if {$n >= 0} {
			set all [lreplace $all $n $n]
			lappend all $t
		    }
		}
		set C($c,dlist) $all
	    }

	    lower {
		lassign $args tags
		set all $C($c,dlist)
		foreach t [tagfind $c $tags] {
		    set n [lsearch -exact $all $t]
		    if {$n >= 0} {
			set all [lreplace $all $n $n]
			set all [linsert $all 0 $t]
		    }
		}
		set C($c,dlist) $all
	    }

	    destroy {
		set cmd $C($c,cmd)
		foreach name [array names C $c,*] {
		    unset C($name)
		}
		rename "::$cmd" {}
	    }

	    delete {
		lassign $args tags
		set all $C($c,dlist)
		foreach t [tagfind $c $tags] {
		    set n [lsearch -exact $all $t]
		    if {$n >= 0} {
			set all [lreplace $all $n $n]
			unset C($c,$t)
		    }
		}
		set C($c,dlist) $all
	    }

	    coords {
		set coords [lassign $args id]
		if {![info exists C($c,$id)]} {
		    foreach item $C($c,dlist) {
			set t [dict get $C($c,$item) -tags]
			if {$id in $t} {
			    if {[llength $coords]} {
				dict set C($c,$item) -coords $coords
			    } else {
				set ret [dict get $C($c,$item) -coords]
			    }
			}
		    }
		} elseif {[llength $coords]} {
		    dict set C($c,$id) -coords $coords
		} else {
		    set ret [dict get $C($c,$id) -coords]
		}
	    }
	    find {
		# find ?withtag?
		set args [lassign $args tags]
		if {$tags eq "withtag"} {
		    lassign $args tags
		}
		set ret [tagfind $c $tags]
	    }

	    svg {
		set vx ""
		set vy ""
		set vw ""
		set vh ""
		lassign $args vx vy vw vh
		package require can2svg
		set xml "<?xml version='1.0'?>\n"
710
711
712
713
714
715
716



717
718
719
720
721
722
723
724
725
726
727
728
729
730
	set C($cid,cmd) $cmd
	set C($cid,dlist) {}
	set C($cid,width) 640
	set C($cid,height) 480
	set C($cid,id) 0
	incr C(cid)
	foreach {key value} $args {



	    switch -glob -- $key {
		-wi* {
		    if {[scan $value %d value]} {
			set C($cid,width) $value
		    }
		}
		-he* {
		    if {[scan $value %d value]} {
			set C($cid,height) $value
		    }
		}
	    }
	}
	return $cmd







>
>
>

|




|







712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
	set C($cid,cmd) $cmd
	set C($cid,dlist) {}
	set C($cid,width) 640
	set C($cid,height) 480
	set C($cid,id) 0
	incr C(cid)
	foreach {key value} $args {
	    if {![catch {tcl::prefix match {-width -height} $key} nkey]} {
		set key $nkey
	    }
	    switch -glob -- $key {
		-width {
		    if {[scan $value %d value]} {
			set C($cid,width) $value
		    }
		}
		-height {
		    if {[scan $value %d value]} {
			set C($cid,height) $value
		    }
		}
	    }
	}
	return $cmd