summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorfvogel <fvogelnew1@free.fr>2021-12-08 23:09:07 (GMT)
committerfvogel <fvogelnew1@free.fr>2021-12-08 23:09:07 (GMT)
commit24b9c08a2154d3ce22ed75e06a324b7eb4ba96c2 (patch)
treec70c193585a01af528c087bb9485a95fc434fe95
parent8b39d8a6c093fc22886ad3041b00d8b82a6fadbc (diff)
parent98ca1fc00fa7d5b8ab24e8630ac36d932fa79776 (diff)
downloadtk-24b9c08a2154d3ce22ed75e06a324b7eb4ba96c2.zip
tk-24b9c08a2154d3ce22ed75e06a324b7eb4ba96c2.tar.gz
tk-24b9c08a2154d3ce22ed75e06a324b7eb4ba96c2.tar.bz2
merge 8.6
-rw-r--r--doc/wm.n67
-rw-r--r--generic/tk.decls8
-rw-r--r--generic/tkImgPhoto.c31
-rw-r--r--generic/tkInt.decls4
-rw-r--r--generic/tkIntDecls.h7
-rw-r--r--generic/tkMenu.c2
-rw-r--r--generic/tkStubInit.c1
-rw-r--r--macosx/tkMacOSXMouseEvent.c139
8 files changed, 179 insertions, 80 deletions
diff --git a/doc/wm.n b/doc/wm.n
index abd9c88..d0b1375 100644
--- a/doc/wm.n
+++ b/doc/wm.n
@@ -607,40 +607,49 @@ been set explicitly to \fBprogram\fR.
.TP
\fBwm protocol \fIwindow\fR ?\fIname\fR? ?\fIcommand\fR?
.
-This command is used to manage window manager protocols such as
-\fBWM_DELETE_WINDOW\fR.
-\fIName\fR is the name of an atom corresponding to a window manager
-protocol, such as \fBWM_DELETE_WINDOW\fR or \fBWM_SAVE_YOURSELF\fR
-or \fBWM_TAKE_FOCUS\fR.
-If both \fIname\fR and \fIcommand\fR are specified, then \fIcommand\fR
-is associated with the protocol specified by \fIname\fR.
-\fIName\fR will be added to \fIwindow\fR's \fBWM_PROTOCOLS\fR
-property to tell the window manager that the application has a
-protocol handler for \fIname\fR, and \fIcommand\fR will
-be invoked in the future whenever the window manager sends a
-message to the client for that protocol.
-In this case the command returns an empty string.
-If \fIname\fR is specified but \fIcommand\fR is not, then the current
-command for \fIname\fR is returned, or an empty string if there
-is no handler defined for \fIname\fR.
-If \fIcommand\fR is specified as an empty string then the current
-handler for \fIname\fR is deleted and it is removed from the
-\fBWM_PROTOCOLS\fR property on \fIwindow\fR; an empty string is
-returned.
-Lastly, if neither \fIname\fR nor \fIcommand\fR is specified, the
-command returns a list of all the protocols for which handlers
-are currently defined for \fIwindow\fR.
+This command is used to manage window manager protocols. The \fIname\fR
+argument in the \fBwm protocol\fR command is the name of an atom corresponding
+to a window manager protocol. Examples include \fBWM_DELETE_WINDOW\fR or
+\fBWM_SAVE_YOURSELF\fR or \fBWM_TAKE_FOCUS\fR.
+.RS
+.PP
+A \fIwindow manager protocol\fR is a class of messages sent from a window
+manager to a Tk application outside of the normal event processing system. The
+main example is the \fBWM_DELETE_WINDOW\fR protocol; these messages are sent
+when the user clicks the close widget in the title bar of a window. Handlers
+for window manager protocols are installed with the \fBwm protocol\fR
+command. As a rule, if no handler has been installed for a protocol by the
+\fBwm protocol\fR command then all messages of that protocol are ignored. The
+\fBWM_DELETE_WINDOW\fR protocol is an exception to this rule. At start-up Tk
+installs a handler for this protocol, which responds by destroying the
+window. The \fBwm protocol\fR command can be used to replace this default
+handler by one which responds differently.
+.RE
.RS
.PP
-Tk always defines a protocol handler for \fBWM_DELETE_WINDOW\fR, even if
-you have not asked for one with \fBwm protocol\fR.
-If a \fBWM_DELETE_WINDOW\fR message arrives when you have not defined
-a handler, then Tk handles the message by destroying the window for
-which it was received.
+The list of available window manager protocols depends on the window manager,
+but all window managers supported by Tk provide \fBWM_DELETE_WINDOW\fR. On the
+Windows platform, a \fBWM_SAVE_YOURSELF\fR message is sent on user logout
+or system restart.
.RE
.RS
.PP
-On the Windows platform, the protocol handler \fBWM_SAVE_YOURSELF\fR is called on user logout or system restart.
+If both \fIname\fR and \fIcommand\fR are specified, then \fIcommand\fR becomes
+the handler for the protocol specified by \fIname\fR. The atom for \fIname\fR
+will be added to \fIwindow\fR's \fBWM_PROTOCOLS\fR property to tell the window
+manager that the application has a handler for the protocol specified by
+\fIname\fR, and \fIcommand\fR will be invoked in the future whenever the
+window manager sends a message of that protocol to the Tk application. In
+this case the \fBwm protocol\fR command returns an empty string. If
+\fIname\fR is specified but \fIcommand\fR is not, then the current handler for
+\fIname\fR is returned, or an empty string if there is no handler defined for
+\fIname\fR (as a special case, the default handler for \fBWM_DELETE_WINDOW\fR
+is not returned). If \fIcommand\fR is specified as an empty string then the
+atom for \fIname\fR is removed from the \fBWM_PROTOCOLS\fR property of
+\fIwindow\fR and the handler is destroyed; an empty string is returned.
+Lastly, if neither \fIname\fR nor \fIcommand\fR is specified, the
+\fBwm protocol\fR command returns a list of all of the protocols for which
+handlers are currently defined for \fIwindow\fR.
.RE
.TP
\fBwm resizable \fIwindow\fR ?\fIwidth height\fR?
diff --git a/generic/tk.decls b/generic/tk.decls
index e891dbb..77cad19 100644
--- a/generic/tk.decls
+++ b/generic/tk.decls
@@ -1165,6 +1165,14 @@ export {
const char *Tk_PkgInitStubsCheck(Tcl_Interp *interp, const char *version,
int exact)
}
+export {
+ void Tk_MainEx(int argc, char **argv, Tcl_AppInitProc *appInitProc,
+ Tcl_Interp *interp)
+}
+export {
+ void Tk_MainExW(int argc, wchar_t **argv,
+ Tcl_AppInitProc *appInitProc, Tcl_Interp *interp);
+}
# Local Variables:
# mode: tcl
diff --git a/generic/tkImgPhoto.c b/generic/tkImgPhoto.c
index b91cacb..9e3c80f 100644
--- a/generic/tkImgPhoto.c
+++ b/generic/tkImgPhoto.c
@@ -631,15 +631,19 @@ ImgPhotoCmd(
* Copy the image data over using Tk_PhotoPutZoomedBlock.
*/
- block.pixelPtr += options.fromX * block.pixelSize
- + options.fromY * block.pitch;
- block.width = options.fromX2 - options.fromX;
- block.height = options.fromY2 - options.fromY;
- result = Tk_PhotoPutZoomedBlock(interp, (Tk_PhotoHandle) modelPtr,
- &block, options.toX, options.toY, options.toX2 - options.toX,
- options.toY2 - options.toY, options.zoomX, options.zoomY,
- options.subsampleX, options.subsampleY,
- options.compositingRule);
+ if (block.pixelPtr) {
+ block.pixelPtr += options.fromX * block.pixelSize
+ + options.fromY * block.pitch;
+ block.width = options.fromX2 - options.fromX;
+ block.height = options.fromY2 - options.fromY;
+ result = Tk_PhotoPutZoomedBlock(interp, (Tk_PhotoHandle) modelPtr,
+ &block, options.toX, options.toY, options.toX2 - options.toX,
+ options.toY2 - options.toY, options.zoomX, options.zoomY,
+ options.subsampleX, options.subsampleY,
+ options.compositingRule);
+ } else {
+ result = TCL_OK;
+ }
/*
* Set the destination image size if the -shrink option was specified.
@@ -660,8 +664,10 @@ ImgPhotoCmd(
return TCL_ERROR;
}
}
- Tk_ImageChanged(modelPtr->tkMaster, 0, 0, 0, 0,
- modelPtr->width, modelPtr->height);
+ if (block.pixelPtr || (options.options & OPT_SHRINK)) {
+ Tk_ImageChanged(modelPtr->tkMaster, 0, 0, 0, 0,
+ modelPtr->width, modelPtr->height);
+ }
if (options.background) {
Tk_FreeColor(options.background);
}
@@ -2095,7 +2101,7 @@ ToggleComplexAlphaIfNeeded(
size_t len = (size_t)MAX(mPtr->userWidth, mPtr->width) *
(size_t)MAX(mPtr->userHeight, mPtr->height) * 4;
unsigned char *c = mPtr->pix32;
- unsigned char *end = c + len;
+ unsigned char *end;
/*
* Set the COMPLEX_ALPHA flag if we have an image with partially
@@ -2106,6 +2112,7 @@ ToggleComplexAlphaIfNeeded(
if (c == NULL) {
return 0;
}
+ end = c + len;
c += 3; /* Start at first alpha byte. */
for (; c < end; c += 4) {
if (*c && *c != 255) {
diff --git a/generic/tkInt.decls b/generic/tkInt.decls
index 2faf410..7f68cf1 100644
--- a/generic/tkInt.decls
+++ b/generic/tkInt.decls
@@ -642,6 +642,9 @@ declare 185 macosx {
declare 186 macosx {
int TkpWillDrawWidget(Tk_Window tkwin)
}
+declare 187 {
+ void TkUnusedStubEntry(void)
+}
##############################################################################
@@ -1829,7 +1832,6 @@ declare 106 aqua {
int XSetClipRectangles(Display *display, GC gc, int clip_x_origin,
int clip_y_origin, XRectangle rectangles[], int n, int ordering)
}
-
declare 107 aqua {
int XFlush(Display *display)
}
diff --git a/generic/tkIntDecls.h b/generic/tkIntDecls.h
index 7057411..cb4379c 100644
--- a/generic/tkIntDecls.h
+++ b/generic/tkIntDecls.h
@@ -558,6 +558,8 @@ EXTERN void TkpRedrawWidget(Tk_Window tkwin);
/* 186 */
EXTERN int TkpWillDrawWidget(Tk_Window tkwin);
#endif /* MACOSX */
+/* 187 */
+EXTERN void TkUnusedStubEntry(void);
typedef struct TkIntStubs {
int magic;
@@ -793,6 +795,7 @@ typedef struct TkIntStubs {
#ifdef MAC_OSX_TCL /* MACOSX */
int (*tkpWillDrawWidget) (Tk_Window tkwin); /* 186 */
#endif /* MACOSX */
+ void (*tkUnusedStubEntry) (void); /* 187 */
} TkIntStubs;
extern const TkIntStubs *tkIntStubsPtr;
@@ -1173,6 +1176,8 @@ extern const TkIntStubs *tkIntStubsPtr;
#define TkpWillDrawWidget \
(tkIntStubsPtr->tkpWillDrawWidget) /* 186 */
#endif /* MACOSX */
+#define TkUnusedStubEntry \
+ (tkIntStubsPtr->tkUnusedStubEntry) /* 187 */
#endif /* defined(USE_TK_STUBS) */
@@ -1224,5 +1229,7 @@ extern const TkIntStubs *tkIntStubsPtr;
# define TkpRedrawWidget(w)
#endif
+#undef TkUnusedStubEntry
+
#endif /* _TKINTDECLS */
diff --git a/generic/tkMenu.c b/generic/tkMenu.c
index 18f59a8..d7c7697 100644
--- a/generic/tkMenu.c
+++ b/generic/tkMenu.c
@@ -302,7 +302,7 @@ static const Tk_OptionSpec tkMenuConfigSpecs[] = {
DEF_MENU_TITLE, Tk_Offset(TkMenu, titlePtr), -1,
TK_OPTION_NULL_OK, NULL, 0},
{TK_OPTION_STRING_TABLE, "-type", "type", "Type",
- DEF_MENU_TYPE, Tk_Offset(TkMenu, menuTypePtr), -1, TK_OPTION_NULL_OK,
+ DEF_MENU_TYPE, Tk_Offset(TkMenu, menuTypePtr), -1, 0,
(ClientData) menuTypeStrings, 0},
{TK_OPTION_END, NULL, NULL, NULL, 0, 0, 0, 0, NULL, 0}
};
diff --git a/generic/tkStubInit.c b/generic/tkStubInit.c
index e637f8e..210bb5f 100644
--- a/generic/tkStubInit.c
+++ b/generic/tkStubInit.c
@@ -520,6 +520,7 @@ static const TkIntStubs tkIntStubs = {
#ifdef MAC_OSX_TCL /* MACOSX */
TkpWillDrawWidget, /* 186 */
#endif /* MACOSX */
+ TkUnusedStubEntry, /* 187 */
};
static const TkIntPlatStubs tkIntPlatStubs = {
diff --git a/macosx/tkMacOSXMouseEvent.c b/macosx/tkMacOSXMouseEvent.c
index a677fa1..5e21142 100644
--- a/macosx/tkMacOSXMouseEvent.c
+++ b/macosx/tkMacOSXMouseEvent.c
@@ -87,12 +87,16 @@ enum {
static Tk_Window target = NULL, dragTarget = NULL;
NSPoint local, global;
NSInteger button;
+ TkWindow *newFocus = NULL;
int win_x, win_y;
unsigned int buttonState = 0;
Bool isTestingEvent = NO;
Bool isMotionEvent = NO;
Bool isOutside = NO;
static Bool isDragging = NO;
+ static Bool ignoreDrags = NO;
+ static Bool ignoreUpDown = NO;
+ static NSTimeInterval timestamp = 0;
#ifdef TK_MAC_DEBUG_EVENTS
TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, theEvent);
@@ -130,6 +134,12 @@ enum {
buttonState &= ~TkGetButtonMask(button);
break;
case NSLeftMouseDragged:
+ if (isOutside && !isDragging) {
+ ignoreDrags = YES;
+ }
+ if (ignoreDrags) {
+ return theEvent;
+ }
isDragging = YES;
dragTarget = target;
case NSRightMouseDragged:
@@ -154,46 +164,51 @@ enum {
break;
case NSLeftMouseUp:
isDragging = NO;
- case NSLeftMouseDown:
-
- /*
- * Ignore left mouse button events which arrive while the app is
- * inactive. These events will be resent after activation, causing
- * duplicate actions when an app is activated by a bound mouse event
- * (see ticket [7bda9882cb]. Also, ignore left mouse button events in
- * the titlebar (see tickets [d72abe6b54] and [39cbacb9e8]).
- */
-
- if (![NSApp isActive] || isOutside) {
+ dragTarget = NULL;
+ if ([theEvent clickCount] == 2) {
+ ignoreUpDown = NO;
+ }
+ if (ignoreUpDown) {
return theEvent;
}
- break;
- case NSMouseMoved:
- if (eventWindow && eventWindow != [NSApp keyWindow]) {
+ if (ignoreDrags) {
+ ignoreDrags = NO;
return theEvent;
}
- isMotionEvent = YES;
break;
- case NSScrollWheel:
-#if 0
- case NSCursorUpdate:
- case NSTabletPoint:
- case NSTabletProximity:
-#endif
- break;
- default: /* This type of event is ignored. */
- return theEvent;
- }
+ case NSLeftMouseDown:
- /*
- * Update the button state. We ignore left button presses that occur
- * outside of the ContentView. We also ignore the first left button press
- * after a live resize ends. (Apple sends the button press event that
- * started the resize after the resize ends. It should not be seen by Tk.)
- * See tickets [d72abe6b54] and [39cbacb9e8].
- */
+ /*
+ * Ignore left mouse button events which are in an NSWindow but outside
+ * of its contentView (see tickets [d72abe6b54] and [39cbacb9e8]).
+ * Ignore the first left button press after a live resize ends. (Apple
+ * sends the button press event that started the resize after the
+ * resize ends. It should not be seen by Tk. See tickets [d72abe6b54]
+ * and [39cbacb9e8]). Ignore button press events when ignoreUpDown is
+ * set. These are extraneous events which appear when double-clicking
+ * in a window without focus, causing duplicate Double-1 events (see
+ * ticket [7bda9882cb]). When a LeftMouseDown event with clickCount 2
+ * is received we set the ignoreUpDown flag and we clear it when the
+ * matching LeftMouseUp with click count 2 is received.
+ */
+
+ /*
+ * Make sure we don't ignore LeftMouseUp and LeftMouseDown forever.
+ * Currently tkBind.c sets NEARBY_MS to 500 (the Windows default).
+ */
- if (eventType == NSLeftMouseDown) {
+ if ([theEvent timestamp] - timestamp > 1) {
+ ignoreUpDown = NO;
+ }
+
+ if ([theEvent clickCount] == 2) {
+ if (ignoreUpDown == YES) {
+ return theEvent;
+ } else {
+ timestamp = [theEvent timestamp];
+ ignoreUpDown = YES;
+ }
+ }
if (!isTestingEvent) {
NSRect bounds = [contentView bounds];
NSRect grip = NSMakeRect(bounds.size.width - 10, 0, 10, 10);
@@ -209,7 +224,48 @@ enum {
return theEvent;
}
}
+
+ /*
+ * If this click will change the focus, the Tk event event should
+ * be sent to the toplevel which will be receiving focus rather than to
+ * the current focus window. So reset tkEventTarget.
+ */
+
+ if (eventWindow != [NSApp keyWindow]) {
+ NSWindow *w;
+
+ if (eventWindow && isOutside) {
+ return theEvent;
+ }
+ for (w in [NSApp orderedWindows]) {
+ if (NSPointInRect([NSEvent mouseLocation], [w frame])) {
+ newFocus = TkMacOSXGetTkWindow(w);
+ break;
+ }
+ }
+ if (newFocus) {
+ [NSApp setTkEventTarget: newFocus];
+ [NSApp setTkPointerWindow: newFocus];
+ target = (Tk_Window) newFocus;
+ }
+ }
buttonState |= TkGetButtonMask(Button1);
+ break;
+ case NSMouseMoved:
+ if (eventWindow && eventWindow != [NSApp keyWindow]) {
+ return theEvent;
+ }
+ isMotionEvent = YES;
+ break;
+ case NSScrollWheel:
+#if 0
+ case NSCursorUpdate:
+ case NSTabletPoint:
+ case NSTabletProximity:
+#endif
+ break;
+ default: /* This type of event is ignored. */
+ return theEvent;
}
/*
@@ -258,7 +314,7 @@ enum {
global.x = floor(global.x);
global.y = floor(TkMacOSXZeroScreenHeight() - global.y);
local.x = floor(local.x);
- local.y = floor([eventWindow frame].size.height - local.y);
+ local.y = floor(eventWindow.frame.size.height - local.y);
if (Tk_IsEmbedded(winPtr)) {
TkWindow *contPtr = TkpGetOtherWindow(winPtr);
if (Tk_IsTopLevel(contPtr)) {
@@ -294,6 +350,16 @@ enum {
for (; w != NULL; w = w->parentPtr) {
win_x -= Tk_X(w);
win_y -= Tk_Y(w);
+ if (Tk_IsTopLevel(w)) {
+
+ /*
+ * Adjust for the titlebar.
+ */
+
+ win_y -= (eventWindow.frame.size.height -
+ contentView.bounds.size.height);
+ break;
+ }
}
target = dragTarget;
} else {
@@ -331,7 +397,6 @@ enum {
unsigned int state = buttonState;
NSUInteger modifiers = [theEvent modifierFlags];
-
if (modifiers & NSAlphaShiftKeyMask) {
state |= LockMask;
}
@@ -358,7 +423,7 @@ enum {
/*
* Send XEvents. We do this here for Motion events outside of the focused
* toplevel and for MouseWheel events. In other cases the XEvents will be
- * sent when we call TkUpdatePointer.
+ * sent when we call Tk_UpdatePointer.
*/
if (eventType != NSScrollWheel) {
@@ -366,7 +431,7 @@ enum {
/*
* When dragging the mouse into the resize area Apple shows the
- * left button to be up, which confuses TkUpdatePointer. So
+ * left button to be up, which confuses Tk_UpdatePointer. So
* we make sure that the button state appears the way that Tk
* expects.
*/