Tk Source Code

Check-in [9e30de65]
Login
EuroTcl/OpenACS 11 - 12 JULY 2024, VIENNA

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

Overview
Comment:Remove debugging code. Issues remain with macOS for other tests in event.test.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | bug-22349fc78a-v2
Files: files | file ages | folders
SHA3-256: 9e30de659d098d0126e3a0243ebaa133146d622c7fec8e82faf507ded984f172
User & Date: culler 2024-05-22 03:16:50
Context
2024-05-22
04:22
Make destruction of windows on macOS work again. But more issues remain. check-in: 3fc41f12 user: culler tags: bug-22349fc78a-v2
03:16
Remove debugging code. Issues remain with macOS for other tests in event.test. check-in: 9e30de65 user: culler tags: bug-22349fc78a-v2
02:44
All event tests now pass on Windows check-in: 34f66244 user: culler tags: bug-22349fc78a-v2
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to generic/tkGrab.c.

994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
				 * being entered (EnterNotify or FocusIn). 0
				 * means don't generate enter events. */
    Tcl_QueuePosition position)	/* Position at which events are added to the
				 * system event queue. */
{
    TkWindow *winPtr;
    int upLevels, downLevels, i, j, focus;
#define NAME(w) (w ? Tk_PathName(w) : "NULL")
    
    fprintf(stderr, "TkInOutEvents: %s -> %s\n",
	    NAME(sourcePtr), NAME(destPtr));

    /*
     * There are four possible cases to deal with:
     *
     * 1. SourcePtr and destPtr are the same. There's nothing to do in this
     *    case.
     * 2. SourcePtr is an ancestor of destPtr in the same top-level window.







<
<
<
<







994
995
996
997
998
999
1000




1001
1002
1003
1004
1005
1006
1007
				 * being entered (EnterNotify or FocusIn). 0
				 * means don't generate enter events. */
    Tcl_QueuePosition position)	/* Position at which events are added to the
				 * system event queue. */
{
    TkWindow *winPtr;
    int upLevels, downLevels, i, j, focus;





    /*
     * There are four possible cases to deal with:
     *
     * 1. SourcePtr and destPtr are the same. There's nothing to do in this
     *    case.
     * 2. SourcePtr is an ancestor of destPtr in the same top-level window.
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
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
	} else {					\
	    eventPtr->xcrossing.detail = d;		\
	    TkChangeEventWindow(eventPtr, w);		\
	}						\
	Tk_QueueWindowEvent(eventPtr, position);	\
    }

#define DBGEV(w, t, d) fprintf(stderr, "    Queueing %s %s for %s\n", t, d, NAME(w))

    if (downLevels == 0) {
	/*
	 * SourcePtr is an inferior of destPtr.
	 */

	if (leaveType != 0) {
	    DBGEV(sourcePtr, "<Leave>", "NotifyAncestor");
	    QUEUE(sourcePtr, leaveType, NotifyAncestor);
	    for (winPtr = sourcePtr->parentPtr, i = upLevels-1; i > 0;
		    winPtr = winPtr->parentPtr, i--) {
		DBGEV(winPtr, "<Leave>", "NotifyVirtual");
		QUEUE(winPtr, leaveType, NotifyVirtual);
	    }
	}
	if ((enterType != 0) && (destPtr != NULL)) {
	    DBGEV(destPtr, "<Enter>", "NotifyVirtual");
	    QUEUE(destPtr, enterType, NotifyInferior);
	}
    } else if (upLevels == 0) {
	/*
	 * DestPtr is an inferior of sourcePtr.
	 */

	if ((leaveType != 0) && (sourcePtr != NULL)) {
	    DBGEV(sourcePtr, "<Leave>", "NotifyInferior");
	    QUEUE(sourcePtr, leaveType, NotifyInferior);
	}
	if (enterType != 0) {
	    for (i = downLevels-1; i > 0; i--) {
		for (winPtr = destPtr->parentPtr, j = 1; j < i;
			winPtr = winPtr->parentPtr, j++) {
		    /* empty */
		}
		DBGEV(winPtr, "<Enter>", "NotifyVirtual");
		QUEUE(winPtr, enterType, NotifyVirtual);
	    }
	    if (destPtr != NULL) {
		DBGEV(winPtr, "<Enter>", "NotifyVirtual");
		QUEUE(destPtr, enterType, NotifyAncestor);
	    }
	}
    } else {
	/*
	 * Non-linear: neither window is an inferior of the other.
	 */

	if (leaveType != 0) {
	    DBGEV(sourcePtr, "<Leave>", "NotifyNonlinear");
	    QUEUE(sourcePtr, leaveType, NotifyNonlinear);
	    for (winPtr = sourcePtr->parentPtr, i = upLevels-1; i > 0;
		    winPtr = winPtr->parentPtr, i--) {
	    DBGEV(winPtr, "<Leave>", "NotifyNonlinearVirtual");
	    QUEUE(winPtr, leaveType, NotifyNonlinearVirtual);
	    }
	}
	if (enterType != 0) {
	    for (i = downLevels-1; i > 0; i--) {
		for (winPtr = destPtr->parentPtr, j = 1; j < i;
			winPtr = winPtr->parentPtr, j++) {
		}
		DBGEV(winPtr, "<Enter>", "NotifyNonlinearVirtual");
		QUEUE(winPtr, enterType, NotifyNonlinearVirtual);
	    }
	    if (destPtr != NULL) {
		DBGEV(destPtr, "<Enter>", "NotifyNonlinear");
		QUEUE(destPtr, enterType, NotifyNonlinear);
	    }
	}
    }
    fflush(stderr);
}








<
<






<



<




<








<








<



<









<



<








<



<







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
1072
1073
1074

1075
1076
1077

1078
1079
1080
1081
1082
1083
1084
1085
1086

1087
1088
1089

1090
1091
1092
1093
1094
1095
1096
1097

1098
1099
1100

1101
1102
1103
1104
1105
1106
1107
	} else {					\
	    eventPtr->xcrossing.detail = d;		\
	    TkChangeEventWindow(eventPtr, w);		\
	}						\
	Tk_QueueWindowEvent(eventPtr, position);	\
    }



    if (downLevels == 0) {
	/*
	 * SourcePtr is an inferior of destPtr.
	 */

	if (leaveType != 0) {

	    QUEUE(sourcePtr, leaveType, NotifyAncestor);
	    for (winPtr = sourcePtr->parentPtr, i = upLevels-1; i > 0;
		    winPtr = winPtr->parentPtr, i--) {

		QUEUE(winPtr, leaveType, NotifyVirtual);
	    }
	}
	if ((enterType != 0) && (destPtr != NULL)) {

	    QUEUE(destPtr, enterType, NotifyInferior);
	}
    } else if (upLevels == 0) {
	/*
	 * DestPtr is an inferior of sourcePtr.
	 */

	if ((leaveType != 0) && (sourcePtr != NULL)) {

	    QUEUE(sourcePtr, leaveType, NotifyInferior);
	}
	if (enterType != 0) {
	    for (i = downLevels-1; i > 0; i--) {
		for (winPtr = destPtr->parentPtr, j = 1; j < i;
			winPtr = winPtr->parentPtr, j++) {
		    /* empty */
		}

		QUEUE(winPtr, enterType, NotifyVirtual);
	    }
	    if (destPtr != NULL) {

		QUEUE(destPtr, enterType, NotifyAncestor);
	    }
	}
    } else {
	/*
	 * Non-linear: neither window is an inferior of the other.
	 */

	if (leaveType != 0) {

	    QUEUE(sourcePtr, leaveType, NotifyNonlinear);
	    for (winPtr = sourcePtr->parentPtr, i = upLevels-1; i > 0;
		    winPtr = winPtr->parentPtr, i--) {

	    QUEUE(winPtr, leaveType, NotifyNonlinearVirtual);
	    }
	}
	if (enterType != 0) {
	    for (i = downLevels-1; i > 0; i--) {
		for (winPtr = destPtr->parentPtr, j = 1; j < i;
			winPtr = winPtr->parentPtr, j++) {
		}

		QUEUE(winPtr, enterType, NotifyNonlinearVirtual);
	    }
	    if (destPtr != NULL) {

		QUEUE(destPtr, enterType, NotifyNonlinear);
	    }
	}
    }
    fflush(stderr);
}


Changes to generic/tkPointer.c.

224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
    TkWindow *winPtr = (TkWindow *)tkwin;
    TkWindow *targetWinPtr;
    XPoint pos;
    XEvent event;
    unsigned changes = (state ^ tsdPtr->lastState) & ALL_BUTTONS;
    int type, b;
    unsigned mask;
    fprintf(stderr, "TkUpdatePointer: %s -> %s\n",
	    tsdPtr->lastWinPtr ? Tk_PathName(tsdPtr->lastWinPtr) : "NULL",
	    tkwin ? Tk_PathName(tkwin) : "NULL");
    fflush(stderr);
    pos.x = x;
    pos.y = y;

    /*
     * Use the current keyboard state, but the old mouse button state since we
     * haven't generated the button events yet.
     */







|
<
<
<







224
225
226
227
228
229
230
231



232
233
234
235
236
237
238
    TkWindow *winPtr = (TkWindow *)tkwin;
    TkWindow *targetWinPtr;
    XPoint pos;
    XEvent event;
    unsigned changes = (state ^ tsdPtr->lastState) & ALL_BUTTONS;
    int type, b;
    unsigned mask;




    pos.x = x;
    pos.y = y;

    /*
     * Use the current keyboard state, but the old mouse button state since we
     * haven't generated the button events yet.
     */
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510

void
TkPointerDeadWindow(
    TkWindow *winPtr)
{
    ThreadSpecificData *tsdPtr =
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
    fprintf(stderr, "TkPointerDeadWindow: %s\n", winPtr ? Tk_PathName(winPtr) : "NULL");
    if (winPtr == tsdPtr->lastWinPtr) {
	//This fails on Windows because the windows version of TkWnDeadWindow
	//does not (yet)  call TkUpdatePointer when a dead toplevel contains the
	//pointer.
	tsdPtr->lastWinPtr = TkGetContainer(winPtr);
    }
    if (winPtr == tsdPtr->grabWinPtr) {
	tsdPtr->grabWinPtr = NULL;
    }
    if (winPtr == tsdPtr->restrictWinPtr) {
	tsdPtr->restrictWinPtr = NULL;







<

<
<
<







489
490
491
492
493
494
495

496



497
498
499
500
501
502
503

void
TkPointerDeadWindow(
    TkWindow *winPtr)
{
    ThreadSpecificData *tsdPtr =
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    if (winPtr == tsdPtr->lastWinPtr) {



	tsdPtr->lastWinPtr = TkGetContainer(winPtr);
    }
    if (winPtr == tsdPtr->grabWinPtr) {
	tsdPtr->grabWinPtr = NULL;
    }
    if (winPtr == tsdPtr->restrictWinPtr) {
	tsdPtr->restrictWinPtr = NULL;

Changes to generic/tkWindow.c.

1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334

1335
1336
1337
1338
1339
1340
1341
1342
 */

static void SendEnterLeaveForDestroy(
    Tk_Window tkwin)
{
#if defined(MAC_OSX_TK) || defined(_WIN32)
    int x, y;
    unsigned int state = TkWinGetModifierState();
    Tk_Window pointerWin;
    TkWindow *containerPtr;


    TkGetPointerCoords(NULL, &x, &y);
    pointerWin = Tk_CoordsToWindow(x, y, tkwin);
    if (pointerWin == tkwin) {
	if (!Tk_IsTopLevel(tkwin)) {
	    containerPtr = TkGetContainer((TkWindow *)pointerWin);
	    Tk_UpdatePointer((Tk_Window) containerPtr, x, y, state);
	}
	else if (pointerWin) {







|



>
|







1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
 */

static void SendEnterLeaveForDestroy(
    Tk_Window tkwin)
{
#if defined(MAC_OSX_TK) || defined(_WIN32)
    int x, y;
    unsigned int state;
    Tk_Window pointerWin;
    TkWindow *containerPtr;

    XQueryPointer(Tk_Display(tkwin), None, NULL, NULL, &x, &y,
		  NULL, NULL, &state);
    pointerWin = Tk_CoordsToWindow(x, y, tkwin);
    if (pointerWin == tkwin) {
	if (!Tk_IsTopLevel(tkwin)) {
	    containerPtr = TkGetContainer((TkWindow *)pointerWin);
	    Tk_UpdatePointer((Tk_Window) containerPtr, x, y, state);
	}
	else if (pointerWin) {

Changes to tests/event.test.

983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
test event-9.13 {pointer window is a toplevel, toplevel destination} -setup {
    setup_win_mousepointer .one
    toplevel .two
    wm geometry .two 300x300+150+150
    wm withdraw .two
    wm deiconify .two
    waitForWindowEvent .two <Enter>
    bind all <Leave> {append result "<Leave> %d %W|" ; puts stderr "=leave=" }
    bind all <Enter> {append result "<Enter> %d %W|" ; puts stderr "-enter=" }
    set result |
} -body {
    destroy .two
    waitForWindowEvent .one <Enter>
    # destroying .one here instead of in cleanup makes the test pass
    destroy .one
    set result







|
|







983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
test event-9.13 {pointer window is a toplevel, toplevel destination} -setup {
    setup_win_mousepointer .one
    toplevel .two
    wm geometry .two 300x300+150+150
    wm withdraw .two
    wm deiconify .two
    waitForWindowEvent .two <Enter>
    bind all <Leave> {append result "<Leave> %d %W|"}
    bind all <Enter> {append result "<Enter> %d %W|"}
    set result |
} -body {
    destroy .two
    waitForWindowEvent .one <Enter>
    # destroying .one here instead of in cleanup makes the test pass
    destroy .one
    set result