diff options
author | fvogel <fvogelnew1@free.fr> | 2021-12-08 23:09:07 (GMT) |
---|---|---|
committer | fvogel <fvogelnew1@free.fr> | 2021-12-08 23:09:07 (GMT) |
commit | 24b9c08a2154d3ce22ed75e06a324b7eb4ba96c2 (patch) | |
tree | c70c193585a01af528c087bb9485a95fc434fe95 | |
parent | 8b39d8a6c093fc22886ad3041b00d8b82a6fadbc (diff) | |
parent | 98ca1fc00fa7d5b8ab24e8630ac36d932fa79776 (diff) | |
download | tk-24b9c08a2154d3ce22ed75e06a324b7eb4ba96c2.zip tk-24b9c08a2154d3ce22ed75e06a324b7eb4ba96c2.tar.gz tk-24b9c08a2154d3ce22ed75e06a324b7eb4ba96c2.tar.bz2 |
merge 8.6
-rw-r--r-- | doc/wm.n | 67 | ||||
-rw-r--r-- | generic/tk.decls | 8 | ||||
-rw-r--r-- | generic/tkImgPhoto.c | 31 | ||||
-rw-r--r-- | generic/tkInt.decls | 4 | ||||
-rw-r--r-- | generic/tkIntDecls.h | 7 | ||||
-rw-r--r-- | generic/tkMenu.c | 2 | ||||
-rw-r--r-- | generic/tkStubInit.c | 1 | ||||
-rw-r--r-- | macosx/tkMacOSXMouseEvent.c | 139 |
8 files changed, 179 insertions, 80 deletions
@@ -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. */ |