Tk Source Code

Check-in [98cb3c6f]
Login
Bounty program for improvements to Tcl and certain Tcl packages.
Tcl 2019 Conference, Houston/TX, US, Nov 4-8
Send your abstracts to [email protected]
or submit via the online form by Sep 9.

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

Overview
Comment:Increase the size of the ring buffer for Aqua, and modify bgerror so it doesn't try (and fail) to post a dialog inside [NSView drawRect].
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | bug-1951abf33d
Files: files | file ages | folders
SHA3-256: 98cb3c6f48aca20fe419a458219307e38509b6efb2a26fbaf9535b08f0b1ee25
User & Date: culler 2019-03-03 17:04:13
Context
2019-03-04
14:46
Disallow transient/master cycles. Fix bgerror for Aqua to avoid hangs when an error occurs in an idle task run by [NSView drawRect]. check-in: fe352f24 user: culler tags: core-8-6-branch
2019-03-03
17:04
Increase the size of the ring buffer for Aqua, and modify bgerror so it doesn't try (and fail) to post a dialog inside [NSView drawRect]. Closed-Leaf check-in: 98cb3c6f user: culler tags: bug-1951abf33d
2019-03-01
16:04
Make it be an error to create a transient/master cycle on Windows. check-in: 09a3a48d user: culler tags: bug-1951abf33d
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to generic/tkBind.c.

80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
 * also demand that the event ring be a bit bigger.  It might be wise to
 * augment the current double-click pattern matching by adding a new
 * DoubleClick modifier bit which could be set based on the clickCount of the
 * Apple NSEvent object.
 */

#ifndef TK_MAC_OSX
  #define EVENT_BUFFER_SIZE 45
#else
  #define EVENT_BUFFER_SIZE 30
#endif

typedef struct Tk_BindingTable_ {
    XEvent eventRing[EVENT_BUFFER_SIZE];
				/* Circular queue of recent events (higher






|







80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
 * also demand that the event ring be a bit bigger.  It might be wise to
 * augment the current double-click pattern matching by adding a new
 * DoubleClick modifier bit which could be set based on the clickCount of the
 * Apple NSEvent object.
 */

#ifndef TK_MAC_OSX
  #define EVENT_BUFFER_SIZE 90
#else
  #define EVENT_BUFFER_SIZE 30
#endif

typedef struct Tk_BindingTable_ {
    XEvent eventRing[EVENT_BUFFER_SIZE];
				/* Circular queue of recent events (higher

Changes to library/bgerror.tcl.

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
#	It tries to execute tkerror, if that fails it posts a dialog box
#	containing the error message and gives the user a chance to ask
#	to see a stack trace.
#
# Arguments:
#	err - The error message.
#
proc ::tk::dialog::error::bgerror err {
    global errorInfo
    variable button

    set info $errorInfo

    set ret [catch {::tkerror $err} msg];
    if {$ret != 1} {return -code $ret $msg}

    # Ok the application's tkerror either failed or was not found
    # we use the default dialog then :



    set windowingsystem [tk windowingsystem]
    if {$windowingsystem eq "aqua"} {
	set ok [mc Ok]
    } else {
	set ok [mc OK]



    }



    # Truncate the message if it is too wide (>maxLine characters) or
    # too tall (>4 lines).  Truncation occurs at the first point at
    # which one of those conditions is met.
    set displayedErr ""
    set lines 0
    set maxLine 45
    foreach line [split $err \n] {






|








|
|
>
>
>


<
<
<
>
>
>
|
|
>
>







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
#	It tries to execute tkerror, if that fails it posts a dialog box
#	containing the error message and gives the user a chance to ask
#	to see a stack trace.
#
# Arguments:
#	err - The error message.
#
proc ::tk::dialog::error::bgerror {err {flag 1}} {
    global errorInfo
    variable button

    set info $errorInfo

    set ret [catch {::tkerror $err} msg];
    if {$ret != 1} {return -code $ret $msg}

    # The application's tkerror either failed or was not found
    # so we use the default dialog.  But on Aqua we cannot display
    # the dialog if the background error occurs in an idle task
    # being processed inside of [NSView drawRect].  In that case
    # we post the dialog as an after task instead.
    set windowingsystem [tk windowingsystem]
    if {$windowingsystem eq "aqua"} {



	if $flag {
	    after 500 [list bgerror "$err" 0]
	    return
	}
    }

    set ok [mc OK]
    # Truncate the message if it is too wide (>maxLine characters) or
    # too tall (>4 lines).  Truncation occurs at the first point at
    # which one of those conditions is met.
    set displayedErr ""
    set lines 0
    set maxLine 45
    foreach line [split $err \n] {

Changes to macosx/tkMacOSXKeyEvent.c.

20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
...
496
497
498
499
500
501
502

503
504
505
506
507
508
509
510
511
512
513
514
...
547
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
...
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
/*
#ifdef TK_MAC_DEBUG
#define TK_MAC_DEBUG_KEYBOARD
#endif
*/
#define NS_KEYLOG 0


static Tk_Window grabWinPtr = NULL;
				/* Current grab window, NULL if no grab. */
static Tk_Window keyboardGrabWinPtr = NULL;
				/* Current keyboard grab window. */
static NSWindow *keyboardGrabNSWindow = nil;
                               /* NSWindow for the current keyboard grab window. */
static NSModalSession modalSession = nil;

static BOOL processingCompose = NO;
................................................................................
    Window grab_window,
    Bool owner_events,
    int pointer_mode,
    int keyboard_mode,
    Time time)
{
    keyboardGrabWinPtr = Tk_IdToWindow(display, grab_window);

    if (keyboardGrabWinPtr && grabWinPtr) {
	NSWindow *w = TkMacOSXDrawableWindow(grab_window);
	MacDrawable *macWin = (MacDrawable *) grab_window;

	if (w && macWin->toplevel->winPtr == (TkWindow*) grabWinPtr) {
	    if (modalSession) {
		Tcl_Panic("XGrabKeyboard: already grabbed");
	    }
	    keyboardGrabNSWindow = w;
	    [w retain];
	    modalSession = [NSApp beginModalSessionForWindow:w];
	}
................................................................................
    }
    keyboardGrabWinPtr = NULL;
}
 
/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXGetCapture --
 *
 * Results:
 *	Returns the current grab window
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

Tk_Window
TkMacOSXGetCapture(void)
{
    return grabWinPtr;
}
 
/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXGetModalSession --
 *
 * Results:
 *	Returns the current modal session
 *
 * Side effects:
 *	None.
................................................................................
 */

MODULE_SCOPE NSModalSession
TkMacOSXGetModalSession(void)
{
    return modalSession;
}
 
/*
 *----------------------------------------------------------------------
 *
 * TkpSetCapture --
 *
 *	This function captures the mouse so that all future events will be
 *	reported to this window, even if the mouse is outside the window. If
 *	the specified window is NULL, then the mouse is released.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Sets the capture flag and captures the mouse.
 *
 *----------------------------------------------------------------------
 */

void
TkpSetCapture(
    TkWindow *winPtr)		/* Capture window, or NULL. */
{
    while (winPtr && !Tk_IsTopLevel(winPtr)) {
	winPtr = winPtr->parentPtr;
    }
    grabWinPtr = (Tk_Window) winPtr;
}
 
/*
 *----------------------------------------------------------------------
 *
 * Tk_SetCaretPos --
 *
 *	This enables correct placement of the XIM caret. This is called by






<
<
<







 







>
|



|







 







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







 







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







20
21
22
23
24
25
26



27
28
29
30
31
32
33
...
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
...
545
546
547
548
549
550
551




















552
553
554
555
556
557
558
...
561
562
563
564
565
566
567




























568
569
570
571
572
573
574
/*
#ifdef TK_MAC_DEBUG
#define TK_MAC_DEBUG_KEYBOARD
#endif
*/
#define NS_KEYLOG 0




static Tk_Window keyboardGrabWinPtr = NULL;
				/* Current keyboard grab window. */
static NSWindow *keyboardGrabNSWindow = nil;
                               /* NSWindow for the current keyboard grab window. */
static NSModalSession modalSession = nil;

static BOOL processingCompose = NO;
................................................................................
    Window grab_window,
    Bool owner_events,
    int pointer_mode,
    int keyboard_mode,
    Time time)
{
    keyboardGrabWinPtr = Tk_IdToWindow(display, grab_window);
    TkWindow *captureWinPtr = (TkWindow *)TkMacOSXGetCapture(); 
    if (keyboardGrabWinPtr && captureWinPtr) {
	NSWindow *w = TkMacOSXDrawableWindow(grab_window);
	MacDrawable *macWin = (MacDrawable *) grab_window;

	if (w && macWin->toplevel->winPtr == (TkWindow*) captureWinPtr) {
	    if (modalSession) {
		Tcl_Panic("XGrabKeyboard: already grabbed");
	    }
	    keyboardGrabNSWindow = w;
	    [w retain];
	    modalSession = [NSApp beginModalSessionForWindow:w];
	}
................................................................................
    }
    keyboardGrabWinPtr = NULL;
}
 
/*
 *----------------------------------------------------------------------
 *




















 * TkMacOSXGetModalSession --
 *
 * Results:
 *	Returns the current modal session
 *
 * Side effects:
 *	None.
................................................................................
 */

MODULE_SCOPE NSModalSession
TkMacOSXGetModalSession(void)
{
    return modalSession;
}




























 
/*
 *----------------------------------------------------------------------
 *
 * Tk_SetCaretPos --
 *
 *	This enables correct placement of the XIM caret. This is called by

Changes to macosx/tkMacOSXMouseEvent.c.

20
21
22
23
24
25
26

27
28
29
30
31
32
33
...
576
577
578
579
580
581
582


















































583
584
585
586
587
588
589
590
typedef struct {
    unsigned int state;
    long delta;
    Window window;
    Point global;
    Point local;
} MouseEventData;


static int		GenerateButtonEvent(MouseEventData *medPtr);
static unsigned int	ButtonModifiers2State(UInt32 buttonState,
					      UInt32 keyModifiers);

#pragma mark TKApplication(TKMouseEvent)

................................................................................
						  pt,
						  buttonState);
    CGWarpMouseCursorPosition(pt);
    CGEventPost(kCGHIDEventTap, theEvent);
    CFRelease(theEvent);
}
 


















































/*
 * Local Variables:
 * mode: objc
 * c-basic-offset: 4
 * fill-column: 79
 * coding: utf-8
 * End:
 */






>







 







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








20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
...
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
typedef struct {
    unsigned int state;
    long delta;
    Window window;
    Point global;
    Point local;
} MouseEventData;
static Tk_Window captureWinPtr = NULL; /* Current capture window; may be NULL. */

static int		GenerateButtonEvent(MouseEventData *medPtr);
static unsigned int	ButtonModifiers2State(UInt32 buttonState,
					      UInt32 keyModifiers);

#pragma mark TKApplication(TKMouseEvent)

................................................................................
						  pt,
						  buttonState);
    CGWarpMouseCursorPosition(pt);
    CGEventPost(kCGHIDEventTap, theEvent);
    CFRelease(theEvent);
}
 
/*
 *----------------------------------------------------------------------
 *
 * TkpSetCapture --
 *
 *	This function captures the mouse so that all future events will be
 *	reported to this window, even if the mouse is outside the window. If
 *	the specified window is NULL, then the mouse is released.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Sets the capture flag and captures the mouse.
 *
 *----------------------------------------------------------------------
 */

void
TkpSetCapture(
    TkWindow *winPtr)		/* Capture window, or NULL. */
{
    while (winPtr && !Tk_IsTopLevel(winPtr)) {
	winPtr = winPtr->parentPtr;
    }
    captureWinPtr = (Tk_Window) winPtr;
}
 
/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXGetCapture --
 *
 * Results:
 *	Returns the current grab window
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

Tk_Window
TkMacOSXGetCapture(void)
{
    return captureWinPtr;
}
 


/*
 * Local Variables:
 * mode: objc
 * c-basic-offset: 4
 * fill-column: 79
 * coding: utf-8
 * End:
 */