Tk Source Code

Check-in [cb6302a6]
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:Fix bug [609e0045f5]: Aqua scrollwheel events have incorrect mouse coordinates.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | bug-609e0045f5
Files: files | file ages | folders
SHA3-256: cb6302a6f56d3f4a91d5ef624583d18aa168bf342dfddc8e36216a021826172c
User & Date: culler 2019-03-04 23:30:15
Original Comment: Fix bug [609e0045f5]: scrollwheel events have incorrect mouse coordinates.
Context
2019-03-14
20:59
Fix typo Closed-Leaf check-in: 77baa1f7 user: fvogel tags: bug-609e0045f5
2019-03-04
23:30
Fix bug [609e0045f5]: Aqua scrollwheel events have incorrect mouse coordinates. check-in: cb6302a6 user: culler tags: bug-609e0045f5
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
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to macosx/tkMacOSXMouseEvent.c.

44
45
46
47
48
49
50
51
52
53
54
55


56
57
58
59



60
61
62
63
64
65
66
..
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
...
178
179
180
181
182
183
184





185
186
187
188



189


190
191
192
193
194
195
196
 * window that it received in a mouse event. If it receives an NSEvent with a
 * Nil window attribute then the saved window is used.
 */

@implementation TKApplication(TKMouseEvent)
- (NSEvent *) tkProcessMouseEvent: (NSEvent *) theEvent
{
#ifdef TK_MAC_DEBUG_EVENTS
    TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, theEvent);
#endif
    NSWindow*    eventWindow = [theEvent window];
    NSEventType	 eventType = [theEvent type];


#if 0
    NSTrackingArea  *trackingArea = nil;
    NSInteger eventNumber, clickCount, buttonNumber;
#endif



    switch (eventType) {
    case NSMouseEntered:
    case NSMouseExited:
    case NSCursorUpdate:
    case NSLeftMouseDown:
    case NSLeftMouseUp:
    case NSRightMouseDown:
................................................................................
	if (_windowWithMouse) {
	    [_windowWithMouse release];
	}
	_windowWithMouse = eventWindow;
	[_windowWithMouse retain];
    }

    /* Create an Xevent to add to the Tk queue. */




    NSPoint global, local = [theEvent locationInWindow];









    if (eventWindow) { /* local will be in window coordinates. */







	global = [eventWindow tkConvertPointToScreen: local];
	local.y = [eventWindow frame].size.height - local.y;
	global.y = tkMacOSXZeroScreenHeight - global.y;





    } else { /* local will be in screen coordinates. */
	if (_windowWithMouse ) {
	    eventWindow = _windowWithMouse;
	    global = local;
	    local = [eventWindow tkConvertPointFromScreen: local];
	    local.y = [eventWindow frame].size.height - local.y;
	    global.y = tkMacOSXZeroScreenHeight - global.y;
	} else { /* We have no window. Use the screen???*/


	    local.y = tkMacOSXZeroScreenHeight - local.y;
	    global = local;
	}
    }




    TkWindow *winPtr = TkMacOSXGetTkWindow(eventWindow);
    Tk_Window tkwin = (Tk_Window) winPtr;

    if (tkwin) {
	TkWindow *grabWinPtr = winPtr->dispPtr->grabWinPtr;
	if (grabWinPtr &&
	    grabWinPtr != winPtr &&
	    !winPtr->dispPtr->grabFlags && /* this means the grab is local. */
	    grabWinPtr->mainPtr == winPtr->mainPtr) {
	    return theEvent;
	}
    } else {

	tkwin = TkMacOSXGetCapture();



    }
    if (!tkwin) {
	TkMacOSXDbgMsg("tkwin == NULL");
	return theEvent; /* Give up.  No window for this event. */
    } else {
	winPtr = (TkWindow *)tkwin;
    }


















    local.x -= winPtr->wmInfoPtr->xInParent;
    local.y -= winPtr->wmInfoPtr->yInParent;







    int win_x, win_y;
    tkwin = Tk_TopCoordsToWindow(tkwin, local.x, local.y, &win_x, &win_y);







    unsigned int state = 0;
    NSInteger button = [theEvent buttonNumber];
    EventRef eventRef = (EventRef)[theEvent eventRef];
    UInt32 buttons;
    OSStatus err = GetEventParameter(eventRef, kEventParamMouseChord,
				     typeUInt32, NULL, sizeof(UInt32), NULL, &buttons);

................................................................................
	state |= Mod3Mask;
    }
    if (modifiers & NSFunctionKeyMask) {
	state |= Mod4Mask;
    }

    if (eventType != NSScrollWheel) {





#ifdef TK_MAC_DEBUG_EVENTS
	TKLog(@"UpdatePointer %p x %f.0 y %f.0 %d", tkwin, global.x, global.y, state);
#endif
	Tk_UpdatePointer(tkwin, global.x, global.y, state);



    } else { /* handle scroll wheel event */


	CGFloat delta;
	int coarseDelta;
	XEvent xEvent;

	xEvent.type = MouseWheelEvent;
	xEvent.xbutton.x = local.x;
	xEvent.xbutton.y = local.y;






<
<
<


>
>




>
>
>







 







|
>
>
>
>

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



>
>
>
>
>
|
<
<
<
<
<
<
<
>
>
|
|
|
|
>
>
>

|
<
<
<
<
<
<
<
<
<
<
<
>

>
>
>




<
<


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



>
>
>
>
>
>


>
>

>
>
>
>







 







>
>
>
>
>




>
>
>
|
>
>







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
..
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
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
...
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
 * window that it received in a mouse event. If it receives an NSEvent with a
 * Nil window attribute then the saved window is used.
 */

@implementation TKApplication(TKMouseEvent)
- (NSEvent *) tkProcessMouseEvent: (NSEvent *) theEvent
{



    NSWindow*    eventWindow = [theEvent window];
    NSEventType	 eventType = [theEvent type];
    TkWindow *winPtr, *grabWinPtr;
    Tk_Window tkwin;
#if 0
    NSTrackingArea  *trackingArea = nil;
    NSInteger eventNumber, clickCount, buttonNumber;
#endif
#ifdef TK_MAC_DEBUG_EVENTS
    TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, theEvent);
#endif
    switch (eventType) {
    case NSMouseEntered:
    case NSMouseExited:
    case NSCursorUpdate:
    case NSLeftMouseDown:
    case NSLeftMouseUp:
    case NSRightMouseDown:
................................................................................
	if (_windowWithMouse) {
	    [_windowWithMouse release];
	}
	_windowWithMouse = eventWindow;
	[_windowWithMouse retain];
    }

    /*
     * Compute the mouse position in Tk screen coordinates (global) and in
     * the Tk coordinates of its containing Tk Window.
     */
    
    NSPoint global, local = [theEvent locationInWindow];

    /*
     * If the event has no NSWindow, try using the cached NSWindow from the
     * last mouse event.
     */

    if (eventWindow == NULL) {
	eventWindow == _windowWithMouse;
    }
    if (eventWindow) {
	
	/*
	 * Set the local mouse position to its NSWindow flipped coordinates,
	 * with the origin at top left, and the global mouse position to the
	 * flipped screen coordinates.
	 */

	global = [eventWindow tkConvertPointToScreen: local];
	local.y = [eventWindow frame].size.height - local.y;
	global.y = tkMacOSXZeroScreenHeight - global.y;

    } else {

	/*
	 * As a last resort, with no NSWindow to work witn, set both local and
	 * global to the screen coordinates.







	 */

	local.y = tkMacOSXZeroScreenHeight - local.y;
	global = local;
    }

    /*
     * Find the toplevel which corresponds to the event NSWindow.
     */

    winPtr = TkMacOSXGetTkWindow(eventWindow);











    if (winPtr == NULL) {
	tkwin = TkMacOSXGetCapture();
	winPtr = (TkWindow *)tkwin;
    } else {
	tkwin = (Tk_Window) winPtr;
    }
    if (!tkwin) {
	TkMacOSXDbgMsg("tkwin == NULL");
	return theEvent; /* Give up.  No window for this event. */


    }

    /*
     * If another toplevel has a grab, we ignore the event.
     */

    grabWinPtr = winPtr->dispPtr->grabWinPtr;
    if (grabWinPtr &&
	grabWinPtr != winPtr &&
	!winPtr->dispPtr->grabFlags && /* this means the grab is local. */
	grabWinPtr->mainPtr == winPtr->mainPtr) {
	return theEvent;
    }

    /*
     * Convert local from NSWindow flipped coordinates to the toplevel's
     * coordinates.
     */
    
    local.x -= winPtr->wmInfoPtr->xInParent;
    local.y -= winPtr->wmInfoPtr->yInParent;

    /*
     * Find the containing Tk window, and convert local into the coordinates
     * of the Tk window.  (The converted local coordinates are only needed
     * for scrollwheel events.)
     */

    int win_x, win_y;
    tkwin = Tk_TopCoordsToWindow(tkwin, local.x, local.y, &win_x, &win_y);
    local.x = win_x;
    local.y = win_y;

    /*
     *  Generate an XEvent for this mouse event.
     */
    
    unsigned int state = 0;
    NSInteger button = [theEvent buttonNumber];
    EventRef eventRef = (EventRef)[theEvent eventRef];
    UInt32 buttons;
    OSStatus err = GetEventParameter(eventRef, kEventParamMouseChord,
				     typeUInt32, NULL, sizeof(UInt32), NULL, &buttons);

................................................................................
	state |= Mod3Mask;
    }
    if (modifiers & NSFunctionKeyMask) {
	state |= Mod4Mask;
    }

    if (eventType != NSScrollWheel) {

	/*
	 * For normal mouse events, Tk_UpdatePointer will send the XEvent.
	 */

#ifdef TK_MAC_DEBUG_EVENTS
	TKLog(@"UpdatePointer %p x %f.0 y %f.0 %d", tkwin, global.x, global.y, state);
#endif
	Tk_UpdatePointer(tkwin, global.x, global.y, state);
    } else {

	/*
	 * For scroll wheel events we need to send the XEvent here.
	 */
	
	CGFloat delta;
	int coarseDelta;
	XEvent xEvent;

	xEvent.type = MouseWheelEvent;
	xEvent.xbutton.x = local.x;
	xEvent.xbutton.y = local.y;