Import Tk 8.6.11

This commit is contained in:
Steve Dower
2021-03-30 00:54:10 +01:00
parent 42c69189d9
commit 070b8750b0
403 changed files with 21608 additions and 16269 deletions

View File

@@ -14,6 +14,8 @@
#include "tkMacOSXPrivate.h"
#include "tkMacOSXConstants.h"
#include "tkMacOSXWm.h"
/*
* Forward declarations of procedures defined later in this file:
@@ -24,7 +26,11 @@ static int DebuggerObjCmd (ClientData dummy, Tcl_Interp *interp,
int objc, Tcl_Obj *const objv[]);
#endif
static int PressButtonObjCmd (ClientData dummy, Tcl_Interp *interp,
int objc, Tcl_Obj *const objv[]);
int objc, Tcl_Obj *const *objv);
static int InjectKeyEventObjCmd (ClientData dummy, Tcl_Interp *interp,
int objc, Tcl_Obj *const *objv);
static int MenuBarHeightObjCmd (ClientData dummy, Tcl_Interp *interp,
int objc, Tcl_Obj *const *objv);
/*
@@ -56,7 +62,8 @@ TkplatformtestInit(
Tcl_CreateObjCommand(interp, "debugger", DebuggerObjCmd, NULL, NULL);
#endif
Tcl_CreateObjCommand(interp, "pressbutton", PressButtonObjCmd, NULL, NULL);
Tcl_CreateObjCommand(interp, "injectkeyevent", InjectKeyEventObjCmd, NULL, NULL);
Tcl_CreateObjCommand(interp, "menubarheight", MenuBarHeightObjCmd, NULL, NULL);
return TCL_OK;
}
@@ -93,45 +100,86 @@ DebuggerObjCmd(
/*
*----------------------------------------------------------------------
*
* TkTestLogDisplay --
* MenuBarHeightObjCmd --
*
* The test image display procedure calls this to determine whether it
* should write a log message recording that it has being run. On OSX
* 10.14 and later, only calls to the display procedure which occur inside
* of the drawRect method should be logged, since those are the only ones
* which actually draw anything. On earlier systems the opposite is true.
* The calls from within the drawRect method are redundant, since the
* first time the display procedure is run it will do the drawing and that
* first call will usually not occur inside of drawRect.
*
* Results:
* On OSX 10.14 and later, returns true if and only if called from
* within [NSView drawRect]. On earlier systems returns false if
* and only if called from with [NSView drawRect].
*
* Side effects:
* None
*
*----------------------------------------------------------------------
*/
MODULE_SCOPE Bool
TkTestLogDisplay(void) {
if ([NSApp macMinorVersion] >= 14) {
return [NSApp isDrawing];
} else {
return ![NSApp isDrawing];
}
}
/*
*----------------------------------------------------------------------
*
* PressButtonObjCmd --
*
* This Tcl command simulates a button press at a specific screen
* location. It injects NSEvents into the NSApplication event queue,
* as opposed to adding events to the Tcl queue as event generate
* would do. One application is for testing the grab command.
* This procedure calls [NSMenu menuBarHeight] and returns the result
* as an integer. Windows can never be placed to overlap the MenuBar,
* so tests need to be aware of its size.
*
* Results:
* A standard Tcl result.
*
* Side effects:
* None.
*
*----------------------------------------------------------------------
*/
static int
MenuBarHeightObjCmd(
TCL_UNUSED(void *), /* Not used. */
Tcl_Interp *interp, /* Not used. */
TCL_UNUSED(int), /* Not used. */
TCL_UNUSED(Tcl_Obj *const *)) /* Not used. */
{
static int height = 0;
if (height == 0) {
height = (int) [[NSApp mainMenu] menuBarHeight];
}
Tcl_SetObjResult(interp, Tcl_NewIntObj(height));
return TCL_OK;
}
/*
*----------------------------------------------------------------------
*
* TkTestLogDisplay --
*
* The test image display procedure calls this to determine whether it
* should write a log message recording that it has being run.
*
* Results:
* Returns true if and only if the NSView of the drawable is the
* current focusView, which on 10.14 and newer systems can only be the
* case when within [NSView drawRect].
*
* Side effects:
* None
*
*----------------------------------------------------------------------
*/
MODULE_SCOPE Bool
TkTestLogDisplay(
Drawable drawable)
{
MacDrawable *macWin = (MacDrawable *)drawable;
NSWindow *win = nil;
if (macWin->toplevel && macWin->toplevel->winPtr &&
macWin->toplevel->winPtr->wmInfoPtr &&
macWin->toplevel->winPtr->wmInfoPtr->window) {
win = macWin->toplevel->winPtr->wmInfoPtr->window;
} else if (macWin->winPtr && macWin->winPtr->wmInfoPtr &&
macWin->winPtr->wmInfoPtr->window) {
win = macWin->winPtr->wmInfoPtr->window;
}
if (win) {
return ([win contentView] == [NSView focusView]);
} else {
return True;
}
}
/*
*----------------------------------------------------------------------
*
* PressButtonObjCmd --
*
* This Tcl command simulates a button press at a specific screen
* location. It injects NSEvents into the NSApplication event queue, as
* opposed to adding events to the Tcl queue as event generate would do.
* One application is for testing the grab command. These events have
* their unused context property set to 1 as a signal indicating that they
* should not be ignored by [NSApp tkProcessMouseEvent].
*
* Results:
* A standard Tcl result.
@@ -142,15 +190,15 @@ TkTestLogDisplay(void) {
*----------------------------------------------------------------------
*/
/* ARGSUSED */
static int
PressButtonObjCmd(
ClientData clientData,
TCL_UNUSED(void *),
Tcl_Interp *interp,
int objc,
Tcl_Obj *const objv[])
{
int x, y, i, value, wNum;
int x = 0, y = 0, i, value;
NSInteger signal = -1;
CGPoint pt;
NSPoint loc;
NSEvent *motion, *press, *release;
@@ -184,15 +232,20 @@ PressButtonObjCmd(
pt.x = loc.x = x;
pt.y = y;
loc.y = ScreenHeight - y;
wNum = 0;
/*
* We set the window number and the eventNumber to -1 as a signal to
* processMouseEvent.
*/
CGWarpMouseCursorPosition(pt);
motion = [NSEvent mouseEventWithType:NSMouseMoved
location:loc
modifierFlags:0
timestamp:GetCurrentEventTime()
windowNumber:wNum
windowNumber:signal
context:nil
eventNumber:0
eventNumber:signal
clickCount:1
pressure:0.0];
[NSApp postEvent:motion atStart:NO];
@@ -200,9 +253,9 @@ PressButtonObjCmd(
location:loc
modifierFlags:0
timestamp:GetCurrentEventTime()
windowNumber:wNum
windowNumber:signal
context:nil
eventNumber:1
eventNumber:signal
clickCount:1
pressure:0.0];
[NSApp postEvent:press atStart:NO];
@@ -210,16 +263,123 @@ PressButtonObjCmd(
location:loc
modifierFlags:0
timestamp:GetCurrentEventTime()
windowNumber:wNum
windowNumber:signal
context:nil
eventNumber:2
eventNumber:signal
clickCount:1
pressure:0.0];
pressure:-1.0];
[NSApp postEvent:release atStart:NO];
return TCL_OK;
}
static int
InjectKeyEventObjCmd(
TCL_UNUSED(void *),
Tcl_Interp *interp,
int objc,
Tcl_Obj *const objv[])
{
static const char *const optionStrings[] = {
"press", "release", "flagschanged", NULL};
NSUInteger types[3] = {NSKeyDown, NSKeyUp, NSFlagsChanged};
static const char *const argStrings[] = {
"-shift", "-control", "-option", "-command", "-function", "-x", "-y", NULL};
enum args {KEYEVENT_SHIFT, KEYEVENT_CONTROL, KEYEVENT_OPTION, KEYEVENT_COMMAND,
KEYEVENT_FUNCTION, KEYEVENT_X, KEYEVENT_Y};
int i, index, keysym, mods = 0, x = 0, y = 0;
NSString *chars = nil, *unmod = nil, *upper, *lower;
NSEvent *keyEvent;
NSUInteger type;
MacKeycode macKC;
if (objc < 3) {
wrongArgs:
Tcl_WrongNumArgs(interp, 1, objv, "option keysym ?arg?");
return TCL_ERROR;
}
if (Tcl_GetIndexFromObj(interp, objv[1], optionStrings, "option", 0,
&index) != TCL_OK) {
return TCL_ERROR;
}
type = types[index];
if (Tcl_GetIntFromObj(interp, objv[2], &keysym) != TCL_OK) {
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"keysym must be an integer"));
Tcl_SetErrorCode(interp, "TK", "TEST", "INJECT", "KEYSYM", NULL);
return TCL_ERROR;
}
macKC.uint = XKeysymToKeycode(NULL, keysym);
for (i = 3; i < objc; i++) {
if (Tcl_GetIndexFromObjStruct(interp, objv[i], argStrings,
sizeof(char *), "option", TCL_EXACT, &index) != TCL_OK) {
return TCL_ERROR;
}
switch ((enum args) index) {
case KEYEVENT_SHIFT:
mods |= NSShiftKeyMask;
break;
case KEYEVENT_CONTROL:
mods |= NSControlKeyMask;
break;
case KEYEVENT_OPTION:
mods |= NSAlternateKeyMask;
break;
case KEYEVENT_COMMAND:
mods |= NSCommandKeyMask;
break;
case KEYEVENT_FUNCTION:
mods |= NSFunctionKeyMask;
break;
case KEYEVENT_X:
if (++i >= objc) {
goto wrongArgs;
}
if (Tcl_GetIntFromObj(interp,objv[i], &x) != TCL_OK) {
return TCL_ERROR;
}
break;
case KEYEVENT_Y:
if (++i >= objc) {
goto wrongArgs;
}
if (Tcl_GetIntFromObj(interp,objv[i], &y) != TCL_OK) {
return TCL_ERROR;
}
break;
}
}
if (type != NSFlagsChanged) {
UniChar keychar = macKC.v.keychar;
chars = [[NSString alloc] initWithCharacters: &keychar length:1];
upper = [chars uppercaseString];
lower = [chars lowercaseString];
if (![upper isEqual: lower] && [chars isEqual: upper]) {
mods |= NSShiftKeyMask;
}
if (mods & NSShiftKeyMask) {
chars = upper;
unmod = lower;
macKC.v.o_s |= INDEX_SHIFT;
} else {
unmod = chars;
}
if (macKC.v.o_s & INDEX_OPTION) {
mods |= NSAlternateKeyMask;
}
}
keyEvent = [NSEvent keyEventWithType:type
location:NSMakePoint(x, y)
modifierFlags:mods
timestamp:GetCurrentEventTime()
windowNumber:0
context:nil
characters:chars
charactersIgnoringModifiers:unmod
isARepeat:NO
keyCode:macKC.v.virtual];
[NSApp postEvent:keyEvent atStart:NO];
return TCL_OK;
}
/*
* Local Variables:
* mode: objc