summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.travis.yml84
-rw-r--r--doc/grab.n10
-rw-r--r--doc/menu.n23
-rw-r--r--doc/ttk_treeview.n3
-rw-r--r--doc/winfo.n3
-rw-r--r--doc/wm.n29
-rw-r--r--generic/tk.h8
-rw-r--r--generic/tk3d.c18
-rw-r--r--generic/tk3d.h4
-rw-r--r--generic/tkBind.c4
-rw-r--r--generic/tkBusy.c9
-rw-r--r--generic/tkButton.c32
-rw-r--r--generic/tkButton.h2
-rw-r--r--generic/tkCanvArc.c40
-rw-r--r--generic/tkCanvBmap.c6
-rw-r--r--generic/tkCanvImg.c2
-rw-r--r--generic/tkCanvLine.c12
-rw-r--r--generic/tkCanvPoly.c38
-rw-r--r--generic/tkCanvText.c26
-rw-r--r--generic/tkCanvUtil.c4
-rw-r--r--generic/tkCanvas.c19
-rw-r--r--generic/tkCanvas.h2
-rw-r--r--generic/tkColor.c10
-rw-r--r--generic/tkColor.h2
-rw-r--r--generic/tkConfig.c12
-rw-r--r--generic/tkCursor.c6
-rw-r--r--generic/tkEntry.c38
-rw-r--r--generic/tkEntry.h4
-rw-r--r--generic/tkEvent.c4
-rw-r--r--generic/tkFocus.c70
-rw-r--r--generic/tkFrame.c8
-rw-r--r--generic/tkGrab.c7
-rw-r--r--generic/tkImage.c2
-rw-r--r--generic/tkImgBmap.c14
-rw-r--r--generic/tkImgGIF.c1
-rw-r--r--generic/tkImgPhInstance.c2
-rw-r--r--generic/tkInt.decls2
-rw-r--r--generic/tkIntPlatDecls.h4
-rw-r--r--generic/tkListbox.c16
-rw-r--r--generic/tkMain.c4
-rw-r--r--generic/tkMenu.c27
-rw-r--r--generic/tkMenu.h14
-rw-r--r--generic/tkMenuDraw.c126
-rw-r--r--generic/tkMenubutton.c26
-rw-r--r--generic/tkMenubutton.h2
-rw-r--r--generic/tkMessage.c10
-rw-r--r--generic/tkOldConfig.c12
-rw-r--r--generic/tkPanedWindow.c16
-rw-r--r--generic/tkPlace.c8
-rw-r--r--generic/tkRectOval.c39
-rw-r--r--generic/tkScale.c63
-rw-r--r--generic/tkScale.h5
-rw-r--r--generic/tkScrollbar.c2
-rw-r--r--generic/tkScrollbar.h2
-rw-r--r--generic/tkSquare.c6
-rw-r--r--generic/tkText.c17
-rw-r--r--generic/tkText.h6
-rw-r--r--generic/tkTextDisp.c112
-rw-r--r--generic/tkTextTag.c2
-rw-r--r--generic/tkWindow.c2
-rw-r--r--generic/ttk/ttkClassicTheme.c2
-rw-r--r--generic/ttk/ttkDefaultTheme.c2
-rw-r--r--generic/ttk/ttkEntry.c12
-rw-r--r--generic/ttk/ttkLabel.c2
-rw-r--r--generic/ttk/ttkState.c6
-rw-r--r--library/bgerror.tcl17
-rw-r--r--library/demos/dialog1.tcl14
-rw-r--r--library/demos/dialog2.tcl3
-rw-r--r--library/demos/puzzle.tcl2
-rw-r--r--library/menu.tcl248
-rw-r--r--library/ttk/altTheme.tcl2
-rw-r--r--library/ttk/aquaTheme.tcl2
-rw-r--r--library/ttk/clamTheme.tcl2
-rw-r--r--library/ttk/classicTheme.tcl2
-rw-r--r--library/ttk/defaults.tcl2
-rw-r--r--library/ttk/vistaTheme.tcl2
-rw-r--r--library/ttk/winTheme.tcl2
-rw-r--r--library/ttk/xpTheme.tcl2
-rw-r--r--macosx/README2
-rw-r--r--macosx/tkMacOSXButton.c144
-rw-r--r--macosx/tkMacOSXDefault.h12
-rw-r--r--macosx/tkMacOSXDialog.c4
-rw-r--r--macosx/tkMacOSXEmbed.c152
-rw-r--r--macosx/tkMacOSXEntry.c4
-rw-r--r--macosx/tkMacOSXEvent.c38
-rw-r--r--macosx/tkMacOSXImage.c2
-rw-r--r--macosx/tkMacOSXInit.c12
-rw-r--r--macosx/tkMacOSXKeyEvent.c79
-rw-r--r--macosx/tkMacOSXMenu.c282
-rw-r--r--macosx/tkMacOSXMenubutton.c246
-rw-r--r--macosx/tkMacOSXMouseEvent.c74
-rw-r--r--macosx/tkMacOSXNotify.c6
-rw-r--r--macosx/tkMacOSXPrivate.h2
-rw-r--r--macosx/tkMacOSXScrlbr.c10
-rw-r--r--macosx/tkMacOSXSend.c2
-rw-r--r--macosx/tkMacOSXSubwindows.c32
-rw-r--r--macosx/tkMacOSXWindowEvent.c23
-rw-r--r--macosx/tkMacOSXWm.c333
-rw-r--r--macosx/tkMacOSXWm.h20
-rw-r--r--tests/imgPhoto.test33
-rw-r--r--tests/menu.test2
-rw-r--r--tests/menubut.test26
-rw-r--r--tests/scale.test59
-rw-r--r--tests/send.test18
-rw-r--r--tests/text.test330
-rw-r--r--tests/unixButton.test24
-rw-r--r--tests/unixEmbed.test636
-rw-r--r--tests/unixWm.test214
-rw-r--r--tests/wm.test22
-rw-r--r--unix/tkUnix3d.c16
-rw-r--r--unix/tkUnixDefault.h2
-rw-r--r--unix/tkUnixEmbed.c28
-rw-r--r--unix/tkUnixMenu.c105
-rw-r--r--unix/tkUnixMenubu.c4
-rw-r--r--unix/tkUnixRFont.c4
-rw-r--r--unix/tkUnixScale.c8
-rw-r--r--unix/tkUnixScrlbr.c12
-rw-r--r--unix/tkUnixWm.c87
-rw-r--r--win/tkWin3d.c8
-rw-r--r--win/tkWinButton.c11
-rw-r--r--win/tkWinDefault.h2
-rw-r--r--win/tkWinDialog.c4
-rw-r--r--win/tkWinDraw.c13
-rw-r--r--win/tkWinEmbed.c9
-rw-r--r--win/tkWinFont.c2
-rw-r--r--win/tkWinImage.c2
-rw-r--r--win/tkWinMenu.c114
-rw-r--r--win/tkWinPort.h4
-rw-r--r--win/tkWinWm.c24
-rw-r--r--win/tkWinX.c14
-rw-r--r--xlib/X11/X.h7
-rw-r--r--xlib/xgc.c10
-rw-r--r--xlib/xutil.c3
133 files changed, 3109 insertions, 1632 deletions
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000..f2095d0
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,84 @@
+sudo: required
+language: c
+addons:
+ apt:
+ packages:
+ - tcl-dev
+ - libx11-dev
+matrix:
+ include:
+ - os: linux
+ dist: trusty
+ compiler: clang
+ env:
+ - BUILD_DIR=unix
+ - os: linux
+ dist: trusty
+ compiler: clang
+ env:
+ - CFGOPT=--disable-shared
+ - BUILD_DIR=unix
+ - os: linux
+ dist: trusty
+ compiler: gcc
+ env:
+ - BUILD_DIR=unix
+ - os: linux
+ dist: trusty
+ compiler: gcc
+ env:
+ - CFGOPT=--disable-shared
+ - BUILD_DIR=unix
+ - os: linux
+ dist: trusty
+ compiler: gcc-4.9
+ addons:
+ apt:
+ sources:
+ - ubuntu-toolchain-r-test
+ packages:
+ - g++-4.9
+ env:
+ - BUILD_DIR=unix
+ - os: linux
+ dist: trusty
+ compiler: gcc-5
+ addons:
+ apt:
+ sources:
+ - ubuntu-toolchain-r-test
+ packages:
+ - g++-5
+ env:
+ - BUILD_DIR=unix
+ - os: linux
+ dist: trusty
+ compiler: gcc-6
+ addons:
+ apt:
+ sources:
+ - ubuntu-toolchain-r-test
+ packages:
+ - g++-6
+ env:
+ - BUILD_DIR=unix
+ - os: linux
+ dist: trusty
+ compiler: gcc-7
+ addons:
+ apt:
+ sources:
+ - ubuntu-toolchain-r-test
+ packages:
+ - g++-7
+ env:
+ - BUILD_DIR=unix
+before_install:
+ - export ERROR_ON_FAILURES=1
+ - cd ${BUILD_DIR}
+install:
+ - test -n "$NO_DIRECT_CONFIGURE" || ./configure ${CFGOPT}
+script:
+ - make
+ # The styles=develop avoids some weird problems on OSX
+ #- test -n "$NO_DIRECT_TEST" || make test styles=develop
diff --git a/doc/grab.n b/doc/grab.n
index 9288e90..cee3ce7 100644
--- a/doc/grab.n
+++ b/doc/grab.n
@@ -61,6 +61,16 @@ The \fBfocus\fR command is still used to determine which window in the
application receives the keyboard events.
The keyboard grab is released when the grab is released.
.PP
+On macOS a global grab affects all windows created by one Tk process.
+No window in that process other than the grab window can even be
+focused, hence no other window receives key or mouse events. A local
+grab on macOS affects all windows created by one Tcl interpreter. It
+is possible to focus any window belonging to the Tk process during a
+local grab but the grab window is the only window created by its
+interpreter which receives key or mouse events. Windows belonging to the
+same process but created by different interpreters continue to receive
+key and mouse events normally.
+.PP
Grabs apply to particular displays. If an application has windows
on multiple displays then it can establish a separate grab on each
display.
diff --git a/doc/menu.n b/doc/menu.n
index 0e91c1f..c6fcec3 100644
--- a/doc/menu.n
+++ b/doc/menu.n
@@ -267,7 +267,7 @@ toplevels are automatically appended after all the Tk-defined items and
a separator. The Window menu on the Mac also allows toggling the
window into a fullscreen state, and managing a tabbed window interface
(multiple windows grouped into a single window) if supported by that
-version of the operating system.
+version of the operating system.
.PP
When Tk sees a .menubar.help menu on the Macintosh, the menu's contents
are appended to the standard Help menu of the user's menubar whenever
@@ -470,18 +470,19 @@ a menu entry does not automatically unpost the menu; the default
bindings normally take care of this before invoking the \fBinvoke\fR
widget command.
.TP
-\fIpathName \fBpost \fIx y\fR
+\fIpathName \fBpost \fIx y\fR ?\fIindex\fR?
.
Arrange for the menu to be displayed on the screen at the root-window
-coordinates given by \fIx\fR and \fIy\fR. These coordinates are
-adjusted if necessary to guarantee that the entire menu is visible on
-the screen. This command normally returns an empty string.
-If the \fB\-postcommand\fR option has been specified, then its value is
-executed as a Tcl script before posting the menu and the result of
-that script is returned as the result of the \fBpost\fR widget
-command.
-If an error returns while executing the command, then the error is
-returned without posting the menu.
+coordinates given by \fIx\fR and \fIy\fR. If an index is specified
+the menu will be located so that the entry with that index is
+displayed at the point. These coordinates are adjusted if necessary to
+guarantee that the entire menu is visible on the screen. This command
+normally returns an empty string. If the \fB\-postcommand\fR option
+has been specified, then its value is executed as a Tcl script before
+posting the menu and the result of that script is returned as the
+result of the \fBpost\fR widget command. If an error returns while
+executing the command, then the error is returned without posting the
+menu.
.TP
\fIpathName \fBpostcascade \fIindex\fR
.
diff --git a/doc/ttk_treeview.n b/doc/ttk_treeview.n
index b81bc62..96565a3 100644
--- a/doc/ttk_treeview.n
+++ b/doc/ttk_treeview.n
@@ -434,6 +434,9 @@ Specifies the font to use when drawing text.
Specifies the item image, in case the item's \fB\-image\fR option is empty.
.\" .PP
.\" \fI(@@@ TODO: sort out order of precedence for options)\fR
+.PP
+Tag priority is decided by the creation order: tags created first receive
+higher priority.
.SH "COLUMN IDENTIFIERS"
.PP
Column identifiers take any of the following forms:
diff --git a/doc/winfo.n b/doc/winfo.n
index bff4973..fed5c39 100644
--- a/doc/winfo.n
+++ b/doc/winfo.n
@@ -73,6 +73,9 @@ to the screen containing \fIwindow\fR; otherwise they refer to the
screen of the application's main window.
If no window in this application contains the point then an empty
string is returned.
+An empty string is also returned if the point lies in the title bar
+or border of its highest containing toplevel in this application.
+(Note that with some window managers the borders may be invisible.)
In selecting the containing window, children are given higher priority
than parents and among siblings the highest one in the stacking order is
chosen.
diff --git a/doc/wm.n b/doc/wm.n
index 0e79306..aae68d9 100644
--- a/doc/wm.n
+++ b/doc/wm.n
@@ -710,20 +710,21 @@ specified then the command returns the current title for the
.TP
\fBwm transient \fIwindow\fR ?\fImaster\fR?
.
-If \fImaster\fR is specified, then the window manager is informed
-that \fIwindow\fR is a transient window (e.g. pull-down menu) working
-on behalf of \fImaster\fR (where \fImaster\fR is the
-path name for a top-level window). If \fImaster\fR
-is specified as an empty string then \fIwindow\fR is marked as not
-being a transient window any more. Otherwise the command
-returns the path name of \fIwindow\fR's current master, or an
-empty string if \fIwindow\fR is not currently a transient window.
-A transient window will mirror state changes in the master and
-inherit the state of the master when initially mapped. It is an
-error to attempt to make a window a transient of itself.
-The window manager may also decorate a transient window differently, removing
-some features normally present (e.g., minimize and maximize buttons) though
-this is entirely at the discretion of the window manager.
+If \fImaster\fR is specified, then the window manager is informed that
+\fIwindow\fR is a transient window (e.g. pull-down menu) working on
+behalf of \fImaster\fR (where \fImaster\fR is the path name for a
+top-level window). If \fImaster\fR is specified as an empty string
+then \fIwindow\fR is marked as not being a transient window any more.
+Otherwise the command returns the path name of \fIwindow\fR's current
+master, or an empty string if \fIwindow\fR is not currently a
+transient window. A transient window will mirror state changes in the
+master and inherit the state of the master when initially mapped. The
+directed graph with an edge from each transient to its master must be
+acyclic. In particular, it is an error to attempt to make a window a
+transient of itself. The window manager may also decorate a transient
+window differently, removing some features normally present (e.g.,
+minimize and maximize buttons) though this is entirely at the
+discretion of the window manager.
.TP
\fBwm withdraw \fIwindow\fR
.
diff --git a/generic/tk.h b/generic/tk.h
index 6f1c98a..f106f1c 100644
--- a/generic/tk.h
+++ b/generic/tk.h
@@ -587,7 +587,11 @@ typedef void (Tk_ClassWorldChangedProc) (ClientData instanceData);
typedef void (Tk_ClassModalProc) (Tk_Window tkwin, XEvent *eventPtr);
typedef struct Tk_ClassProcs {
+#if TCL_MAJOR_VERSION > 8
+ size_t size;
+#else
unsigned int size;
+#endif
Tk_ClassWorldChangedProc *worldChangedProc;
/* Procedure to invoke when the widget needs
* to respond in some way to a change in the
@@ -617,7 +621,7 @@ typedef struct Tk_ClassProcs {
#define Tk_GetClassProc(procs, which) \
(((procs) == NULL) ? NULL : \
- (((procs)->size <= Tk_Offset(Tk_ClassProcs, which)) ? NULL:(procs)->which))
+ (((procs)->size <= (size_t)Tk_Offset(Tk_ClassProcs, which)) ? NULL:(procs)->which))
/*
* Each geometry manager (the packer, the placer, etc.) is represented by a
@@ -1481,6 +1485,7 @@ typedef struct Tk_ElementSpec {
*----------------------------------------------------------------------
*/
+#if !defined(TK_NO_DEPRECATED) && TCL_MAJOR_VERSION < 9
#define TK_READABLE TCL_READABLE
#define TK_WRITABLE TCL_WRITABLE
#define TK_EXCEPTION TCL_EXCEPTION
@@ -1514,6 +1519,7 @@ typedef struct Tk_ElementSpec {
#define Tk_FreeProc Tcl_FreeProc
#define Tk_Preserve Tcl_Preserve
#define Tk_Release Tcl_Release
+#endif
/* Removed Tk_Main, use macro instead */
#if defined(_WIN32) || defined(__CYGWIN__)
diff --git a/generic/tk3d.c b/generic/tk3d.c
index 0fa061e..92a7803 100644
--- a/generic/tk3d.c
+++ b/generic/tk3d.c
@@ -236,9 +236,9 @@ Tk_Get3DBorder(
borderPtr->darkColorPtr = NULL;
borderPtr->lightColorPtr = NULL;
borderPtr->shadow = None;
- borderPtr->bgGC = None;
- borderPtr->darkGC = None;
- borderPtr->lightGC = None;
+ borderPtr->bgGC = NULL;
+ borderPtr->darkGC = NULL;
+ borderPtr->lightGC = NULL;
borderPtr->hashPtr = hashPtr;
borderPtr->nextPtr = existingBorderPtr;
Tcl_SetHashValue(hashPtr, borderPtr);
@@ -374,7 +374,7 @@ Tk_3DBorderGC(
{
TkBorder * borderPtr = (TkBorder *) border;
- if ((borderPtr->lightGC == None) && (which != TK_3D_FLAT_GC)) {
+ if ((borderPtr->lightGC == NULL) && (which != TK_3D_FLAT_GC)) {
TkpGetShadows(borderPtr, tkwin);
}
if (which == TK_3D_FLAT_GC) {
@@ -391,7 +391,7 @@ Tk_3DBorderGC(
* compilers happy.
*/
- return (GC) None;
+ return NULL;
}
/*
@@ -439,13 +439,13 @@ Tk_Free3DBorder(
if (borderPtr->shadow != None) {
Tk_FreeBitmap(display, borderPtr->shadow);
}
- if (borderPtr->bgGC != None) {
+ if (borderPtr->bgGC != NULL) {
Tk_FreeGC(display, borderPtr->bgGC);
}
- if (borderPtr->darkGC != None) {
+ if (borderPtr->darkGC != NULL) {
Tk_FreeGC(display, borderPtr->darkGC);
}
- if (borderPtr->lightGC != None) {
+ if (borderPtr->lightGC != NULL) {
Tk_FreeGC(display, borderPtr->lightGC);
}
if (prevPtr == borderPtr) {
@@ -765,7 +765,7 @@ Tk_Draw3DPolygon(
int i, lightOnLeft, dx, dy, parallel, pointsSeen;
Display *display = Tk_Display(tkwin);
- if (borderPtr->lightGC == None) {
+ if (borderPtr->lightGC == NULL) {
TkpGetShadows(borderPtr, tkwin);
}
diff --git a/generic/tk3d.h b/generic/tk3d.h
index f574de7..d36b95e 100644
--- a/generic/tk3d.h
+++ b/generic/tk3d.h
@@ -54,10 +54,10 @@ typedef struct TkBorder {
GC bgGC; /* Used (if necessary) to draw areas in the
* background color. */
GC darkGC; /* Used to draw darker parts of the border.
- * None means the shadow colors haven't been
+ * NULL means the shadow colors haven't been
* allocated yet.*/
GC lightGC; /* Used to draw lighter parts of the border.
- * None means the shadow colors haven't been
+ * NULL means the shadow colors haven't been
* allocated yet. */
Tcl_HashEntry *hashPtr; /* Entry in borderTable (needed in order to
* delete structure). */
diff --git a/generic/tkBind.c b/generic/tkBind.c
index 469725e..953d936 100644
--- a/generic/tkBind.c
+++ b/generic/tkBind.c
@@ -84,7 +84,7 @@ typedef union {
*/
#ifndef TK_MAC_OSX
- #define EVENT_BUFFER_SIZE 45
+ #define EVENT_BUFFER_SIZE 90
#else
#define EVENT_BUFFER_SIZE 30
#endif
@@ -3587,7 +3587,7 @@ DoWarp(
if (dispPtr->warpWindow) {
Tcl_Release(dispPtr->warpWindow);
- dispPtr->warpWindow = None;
+ dispPtr->warpWindow = NULL;
}
dispPtr->flags &= ~TK_DISPLAY_IN_WARP;
}
diff --git a/generic/tkBusy.c b/generic/tkBusy.c
index 97fa13d..4dee047 100644
--- a/generic/tkBusy.c
+++ b/generic/tkBusy.c
@@ -519,7 +519,8 @@ CreateBusy(
Tk_Window tkRef) /* Window hosting the busy window */
{
Busy *busyPtr;
- int length, x, y;
+ size_t length;
+ int x, y;
const char *fmt;
char *name;
Tk_Window tkBusy, tkChild, tkParent;
@@ -568,7 +569,7 @@ CreateBusy(
busyPtr->height = Tk_Height(tkRef);
busyPtr->x = Tk_X(tkRef);
busyPtr->y = Tk_Y(tkRef);
- busyPtr->cursor = None;
+ busyPtr->cursor = NULL;
Tk_SetClass(tkBusy, "Busy");
busyPtr->optionTable = Tk_CreateOptionTable(interp, busyOptionSpecs);
if (Tk_InitOptions(interp, busyPtr, busyPtr->optionTable,
@@ -598,7 +599,7 @@ CreateBusy(
*/
Tk_ManageGeometry(tkBusy, &busyMgrInfo, busyPtr);
- if (busyPtr->cursor != None) {
+ if (busyPtr->cursor != NULL) {
Tk_DefineCursor(tkBusy, busyPtr->cursor);
}
@@ -643,7 +644,7 @@ ConfigureBusy(
return TCL_ERROR;
}
if (busyPtr->cursor != oldCursor) {
- if (busyPtr->cursor == None) {
+ if (busyPtr->cursor == NULL) {
Tk_UndefineCursor(busyPtr->tkBusy);
} else {
Tk_DefineCursor(busyPtr->tkBusy, busyPtr->cursor);
diff --git a/generic/tkButton.c b/generic/tkButton.c
index f8944fe..e05fbe2 100644
--- a/generic/tkButton.c
+++ b/generic/tkButton.c
@@ -710,12 +710,12 @@ ButtonCreate(
butPtr->normalFg = NULL;
butPtr->activeFg = NULL;
butPtr->disabledFg = NULL;
- butPtr->normalTextGC = None;
- butPtr->activeTextGC = None;
- butPtr->disabledGC = None;
- butPtr->stippleGC = None;
+ butPtr->normalTextGC = NULL;
+ butPtr->activeTextGC = NULL;
+ butPtr->disabledGC = NULL;
+ butPtr->stippleGC = NULL;
butPtr->gray = None;
- butPtr->copyGC = None;
+ butPtr->copyGC = NULL;
butPtr->widthPtr = NULL;
butPtr->width = 0;
butPtr->heightPtr = NULL;
@@ -740,7 +740,7 @@ ButtonCreate(
butPtr->onValuePtr = NULL;
butPtr->offValuePtr = NULL;
butPtr->tristateValuePtr = NULL;
- butPtr->cursor = None;
+ butPtr->cursor = NULL;
butPtr->takeFocusPtr = NULL;
butPtr->commandPtr = NULL;
butPtr->flags = 0;
@@ -981,22 +981,22 @@ DestroyButton(
if (butPtr->tristateImage != NULL) {
Tk_FreeImage(butPtr->tristateImage);
}
- if (butPtr->normalTextGC != None) {
+ if (butPtr->normalTextGC != NULL) {
Tk_FreeGC(butPtr->display, butPtr->normalTextGC);
}
- if (butPtr->activeTextGC != None) {
+ if (butPtr->activeTextGC != NULL) {
Tk_FreeGC(butPtr->display, butPtr->activeTextGC);
}
- if (butPtr->disabledGC != None) {
+ if (butPtr->disabledGC != NULL) {
Tk_FreeGC(butPtr->display, butPtr->disabledGC);
}
- if (butPtr->stippleGC != None) {
+ if (butPtr->stippleGC != NULL) {
Tk_FreeGC(butPtr->display, butPtr->stippleGC);
}
if (butPtr->gray != None) {
Tk_FreeBitmap(butPtr->display, butPtr->gray);
}
- if (butPtr->copyGC != None) {
+ if (butPtr->copyGC != NULL) {
Tk_FreeGC(butPtr->display, butPtr->copyGC);
}
if (butPtr->textLayout != NULL) {
@@ -1367,7 +1367,7 @@ TkButtonWorldChanged(
gcValues.graphics_exposures = False;
mask = GCForeground | GCBackground | GCFont | GCGraphicsExposures;
newGC = Tk_GetGC(butPtr->tkwin, mask, &gcValues);
- if (butPtr->normalTextGC != None) {
+ if (butPtr->normalTextGC != NULL) {
Tk_FreeGC(butPtr->display, butPtr->normalTextGC);
}
butPtr->normalTextGC = newGC;
@@ -1377,7 +1377,7 @@ TkButtonWorldChanged(
gcValues.background = Tk_3DBorderColor(butPtr->activeBorder)->pixel;
mask = GCForeground | GCBackground | GCFont;
newGC = Tk_GetGC(butPtr->tkwin, mask, &gcValues);
- if (butPtr->activeTextGC != None) {
+ if (butPtr->activeTextGC != NULL) {
Tk_FreeGC(butPtr->display, butPtr->activeTextGC);
}
butPtr->activeTextGC = newGC;
@@ -1389,7 +1389,7 @@ TkButtonWorldChanged(
* Create the GC that can be used for stippling
*/
- if (butPtr->stippleGC == None) {
+ if (butPtr->stippleGC == NULL) {
gcValues.foreground = gcValues.background;
mask = GCForeground;
if (butPtr->gray == None) {
@@ -1415,12 +1415,12 @@ TkButtonWorldChanged(
gcValues.foreground = gcValues.background;
}
newGC = Tk_GetGC(butPtr->tkwin, mask, &gcValues);
- if (butPtr->disabledGC != None) {
+ if (butPtr->disabledGC != NULL) {
Tk_FreeGC(butPtr->display, butPtr->disabledGC);
}
butPtr->disabledGC = newGC;
- if (butPtr->copyGC == None) {
+ if (butPtr->copyGC == NULL) {
butPtr->copyGC = Tk_GetGC(butPtr->tkwin, 0, &gcValues);
}
diff --git a/generic/tkButton.h b/generic/tkButton.h
index 7ed464f..7e04fb9 100644
--- a/generic/tkButton.h
+++ b/generic/tkButton.h
@@ -235,7 +235,7 @@ typedef struct {
* Miscellaneous information:
*/
- Tk_Cursor cursor; /* Value of -cursor option: if not None,
+ Tk_Cursor cursor; /* Value of -cursor option: if not NULL,
* specifies current cursor for window. */
Tcl_Obj *takeFocusPtr; /* Value of -takefocus option; not used in the
* C code, but used by keyboard traversal
diff --git a/generic/tkCanvArc.c b/generic/tkCanvArc.c
index 85a0bab..d2daa17 100644
--- a/generic/tkCanvArc.c
+++ b/generic/tkCanvArc.c
@@ -299,7 +299,7 @@ CreateArc(
arcPtr->activeFillStipple = None;
arcPtr->disabledFillStipple = None;
arcPtr->style = PIESLICE_STYLE;
- arcPtr->fillGC = None;
+ arcPtr->fillGC = NULL;
arcPtr->height = 0;
/*
@@ -508,9 +508,9 @@ ConfigureArc(
mask |= GCCapStyle;
newGC = Tk_GetGC(tkwin, mask, &gcValues);
} else {
- newGC = None;
+ newGC = NULL;
}
- if (arcPtr->outline.gc != None) {
+ if (arcPtr->outline.gc != NULL) {
Tk_FreeGC(Tk_Display(tkwin), arcPtr->outline.gc);
}
arcPtr->outline.gc = newGC;
@@ -542,9 +542,9 @@ ConfigureArc(
}
if (arcPtr->style == ARC_STYLE) {
- newGC = None;
+ newGC = NULL;
} else if (color == NULL) {
- newGC = None;
+ newGC = NULL;
} else {
gcValues.foreground = color->pixel;
if (arcPtr->style == CHORD_STYLE) {
@@ -560,7 +560,7 @@ ConfigureArc(
}
newGC = Tk_GetGC(tkwin, mask, &gcValues);
}
- if (arcPtr->fillGC != None) {
+ if (arcPtr->fillGC != NULL) {
Tk_FreeGC(Tk_Display(tkwin), arcPtr->fillGC);
}
arcPtr->fillGC = newGC;
@@ -717,7 +717,7 @@ DeleteArc(
if (arcPtr->disabledFillStipple != None) {
Tk_FreeBitmap(display, arcPtr->disabledFillStipple);
}
- if (arcPtr->fillGC != None) {
+ if (arcPtr->fillGC != NULL) {
Tk_FreeGC(display, arcPtr->fillGC);
}
}
@@ -848,7 +848,7 @@ ComputeArcBbox(
* drawn) and add one extra pixel just for safety.
*/
- if (arcPtr->outline.gc == None) {
+ if (arcPtr->outline.gc == NULL) {
tmp = 1;
} else {
tmp = (int) ((width + 1.0)/2.0 + 1);
@@ -947,7 +947,7 @@ DisplayArc(
* window servers to crash and should be a no-op anyway.
*/
- if ((arcPtr->fillGC != None) && (extent != 0)) {
+ if ((arcPtr->fillGC != NULL) && (extent != 0)) {
if (stipple != None) {
int w = 0;
int h = 0;
@@ -981,7 +981,7 @@ DisplayArc(
XSetTSOrigin(display, arcPtr->fillGC, 0, 0);
}
}
- if (arcPtr->outline.gc != None) {
+ if (arcPtr->outline.gc != NULL) {
Tk_ChangeOutlineGC(canvas, itemPtr, &(arcPtr->outline));
if (extent != 0) {
@@ -1019,13 +1019,13 @@ DisplayArc(
} else {
if (arcPtr->style == CHORD_STYLE) {
TkFillPolygon(canvas, arcPtr->outlinePtr, CHORD_OUTLINE_PTS,
- display, drawable, arcPtr->outline.gc, None);
+ display, drawable, arcPtr->outline.gc, NULL);
} else if (arcPtr->style == PIESLICE_STYLE) {
TkFillPolygon(canvas, arcPtr->outlinePtr, PIE_OUTLINE1_PTS,
- display, drawable, arcPtr->outline.gc, None);
+ display, drawable, arcPtr->outline.gc, NULL);
TkFillPolygon(canvas, arcPtr->outlinePtr + 2*PIE_OUTLINE1_PTS,
PIE_OUTLINE2_PTS, display, drawable,
- arcPtr->outline.gc, None);
+ arcPtr->outline.gc, NULL);
}
}
@@ -1131,12 +1131,12 @@ ArcToPoint(
return dist;
}
- if ((arcPtr->fillGC != None) || (arcPtr->outline.gc == None)) {
+ if ((arcPtr->fillGC != NULL) || (arcPtr->outline.gc == NULL)) {
filled = 1;
} else {
filled = 0;
}
- if (arcPtr->outline.gc == None) {
+ if (arcPtr->outline.gc == NULL) {
width = 0.0;
}
@@ -1258,12 +1258,12 @@ ArcToArea(
}
}
- if ((arcPtr->fillGC != None) || (arcPtr->outline.gc == None)) {
+ if ((arcPtr->fillGC != NULL) || (arcPtr->outline.gc == NULL)) {
filled = 1;
} else {
filled = 0;
}
- if (arcPtr->outline.gc == None) {
+ if (arcPtr->outline.gc == NULL) {
width = 0.0;
}
@@ -1997,7 +1997,7 @@ ArcToPostscript(
* arc.
*/
- if (arcPtr->fillGC != None) {
+ if (arcPtr->fillGC != NULL) {
Tcl_AppendPrintfToObj(psObj,
"matrix currentmatrix\n"
"%.15g %.15g translate %.15g %.15g scale\n",
@@ -2026,7 +2026,7 @@ ArcToPostscript(
}
Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));
- if (arcPtr->outline.gc != None) {
+ if (arcPtr->outline.gc != NULL) {
Tcl_AppendToObj(psObj, "grestore gsave\n", -1);
}
} else {
@@ -2038,7 +2038,7 @@ ArcToPostscript(
* If there's an outline for the arc, draw it.
*/
- if (arcPtr->outline.gc != None) {
+ if (arcPtr->outline.gc != NULL) {
Tcl_AppendPrintfToObj(psObj,
"matrix currentmatrix\n"
"%.15g %.15g translate %.15g %.15g scale\n",
diff --git a/generic/tkCanvBmap.c b/generic/tkCanvBmap.c
index d7d54f4..b9de07b 100644
--- a/generic/tkCanvBmap.c
+++ b/generic/tkCanvBmap.c
@@ -189,7 +189,7 @@ TkcCreateBitmap(
bmapPtr->bgColor = NULL;
bmapPtr->activeBgColor = NULL;
bmapPtr->disabledBgColor = NULL;
- bmapPtr->gc = None;
+ bmapPtr->gc = NULL;
/*
* Process the arguments to fill in the item record. Only 1 (list) or 2 (x
@@ -372,7 +372,7 @@ ConfigureBitmap(
}
if (bitmap == None) {
- newGC = None;
+ newGC = NULL;
} else {
gcValues.foreground = fgColor->pixel;
mask = GCForeground;
@@ -385,7 +385,7 @@ ConfigureBitmap(
}
newGC = Tk_GetGC(tkwin, mask, &gcValues);
}
- if (bmapPtr->gc != None) {
+ if (bmapPtr->gc != NULL) {
Tk_FreeGC(Tk_Display(tkwin), bmapPtr->gc);
}
bmapPtr->gc = newGC;
diff --git a/generic/tkCanvImg.c b/generic/tkCanvImg.c
index 899741a..70b9c79 100644
--- a/generic/tkCanvImg.c
+++ b/generic/tkCanvImg.c
@@ -449,7 +449,7 @@ ComputeImageBbox(
x = (int) (imgPtr->x + ((imgPtr->x >= 0) ? 0.5 : - 0.5));
y = (int) (imgPtr->y + ((imgPtr->y >= 0) ? 0.5 : - 0.5));
- if ((state == TK_STATE_HIDDEN) || (image == None)) {
+ if ((state == TK_STATE_HIDDEN) || (image == NULL)) {
imgPtr->header.x1 = imgPtr->header.x2 = x;
imgPtr->header.y1 = imgPtr->header.y2 = y;
return;
diff --git a/generic/tkCanvLine.c b/generic/tkCanvLine.c
index 087aa56..b6c845d 100644
--- a/generic/tkCanvLine.c
+++ b/generic/tkCanvLine.c
@@ -296,7 +296,7 @@ CreateLine(
linePtr->coordPtr = NULL;
linePtr->capStyle = CapButt;
linePtr->joinStyle = JoinRound;
- linePtr->arrowGC = None;
+ linePtr->arrowGC = NULL;
linePtr->arrow = ARROWS_NONE;
linePtr->arrowShapeA = (float)8.0;
linePtr->arrowShapeB = (float)10.0;
@@ -521,12 +521,12 @@ ConfigureLine(
#endif
arrowGC = Tk_GetGC(tkwin, mask, &gcValues);
} else {
- newGC = arrowGC = None;
+ newGC = arrowGC = NULL;
}
- if (linePtr->outline.gc != None) {
+ if (linePtr->outline.gc != NULL) {
Tk_FreeGC(Tk_Display(tkwin), linePtr->outline.gc);
}
- if (linePtr->arrowGC != None) {
+ if (linePtr->arrowGC != NULL) {
Tk_FreeGC(Tk_Display(tkwin), linePtr->arrowGC);
}
linePtr->outline.gc = newGC;
@@ -611,7 +611,7 @@ DeleteLine(
if (linePtr->coordPtr != NULL) {
ckfree(linePtr->coordPtr);
}
- if (linePtr->arrowGC != None) {
+ if (linePtr->arrowGC != NULL) {
Tk_FreeGC(display, linePtr->arrowGC);
}
if (linePtr->firstArrowPtr != NULL) {
@@ -840,7 +840,7 @@ DisplayLine(
int numPoints;
Tk_State state = itemPtr->state;
- if ((!linePtr->numPoints) || (linePtr->outline.gc == None)) {
+ if (!linePtr->numPoints || (linePtr->outline.gc == NULL)) {
return;
}
diff --git a/generic/tkCanvPoly.c b/generic/tkCanvPoly.c
index b4ef098..6a8f865 100644
--- a/generic/tkCanvPoly.c
+++ b/generic/tkCanvPoly.c
@@ -273,7 +273,7 @@ CreatePolygon(
polyPtr->fillStipple = None;
polyPtr->activeFillStipple = None;
polyPtr->disabledFillStipple = None;
- polyPtr->fillGC = None;
+ polyPtr->fillGC = NULL;
polyPtr->smooth = NULL;
polyPtr->splineSteps = 12;
polyPtr->autoClosed = 0;
@@ -478,9 +478,9 @@ ConfigurePolygon(
mask |= GCCapStyle|GCJoinStyle;
newGC = Tk_GetGC(tkwin, mask, &gcValues);
} else {
- newGC = None;
+ newGC = NULL;
}
- if (polyPtr->outline.gc != None) {
+ if (polyPtr->outline.gc != NULL) {
Tk_FreeGC(Tk_Display(tkwin), polyPtr->outline.gc);
}
polyPtr->outline.gc = newGC;
@@ -504,7 +504,7 @@ ConfigurePolygon(
}
if (color == NULL) {
- newGC = None;
+ newGC = NULL;
} else {
gcValues.foreground = color->pixel;
mask = GCForeground;
@@ -518,13 +518,13 @@ ConfigurePolygon(
* Mac OS X CG drawing needs access to the outline linewidth
* even for fills (as linewidth controls antialiasing).
*/
- gcValues.line_width = polyPtr->outline.gc != None ?
+ gcValues.line_width = polyPtr->outline.gc != NULL ?
polyPtr->outline.gc->line_width : 0;
mask |= GCLineWidth;
#endif
newGC = Tk_GetGC(tkwin, mask, &gcValues);
}
- if (polyPtr->fillGC != None) {
+ if (polyPtr->fillGC != NULL) {
Tk_FreeGC(Tk_Display(tkwin), polyPtr->fillGC);
}
polyPtr->fillGC = newGC;
@@ -590,7 +590,7 @@ DeletePolygon(
if (polyPtr->disabledFillStipple != None) {
Tk_FreeBitmap(display, polyPtr->disabledFillStipple);
}
- if (polyPtr->fillGC != None) {
+ if (polyPtr->fillGC != NULL) {
Tk_FreeGC(display, polyPtr->fillGC);
}
}
@@ -694,7 +694,7 @@ ComputePolygonBbox(
}
}
- if (polyPtr->outline.gc != None) {
+ if (polyPtr->outline.gc != NULL) {
tsoffset = &polyPtr->outline.tsoffset;
if (tsoffset) {
if (tsoffset->flags & TK_OFFSET_INDEX) {
@@ -836,11 +836,11 @@ TkFillPolygon(
* allocated.
*/
- if (gc != None && numPoints > 3) {
+ if (gc != NULL && numPoints > 3) {
XFillPolygon(display, drawable, gc, pointPtr, numPoints, Complex,
CoordModeOrigin);
}
- if (outlineGC != None) {
+ if (outlineGC != NULL) {
XDrawLines(display, drawable, outlineGC, pointPtr, numPoints,
CoordModeOrigin);
}
@@ -881,9 +881,9 @@ DisplayPolygon(
Pixmap stipple = polyPtr->fillStipple;
double linewidth = polyPtr->outline.width;
- if (((polyPtr->fillGC == None) && (polyPtr->outline.gc == None)) ||
+ if (((polyPtr->fillGC == NULL) && (polyPtr->outline.gc == NULL)) ||
(polyPtr->numPoints < 1) ||
- (polyPtr->numPoints < 3 && polyPtr->outline.gc == None)) {
+ (polyPtr->numPoints < 3 && polyPtr->outline.gc == NULL)) {
return;
}
@@ -911,7 +911,7 @@ DisplayPolygon(
* reset the offset when done, since the GC is supposed to be read-only.
*/
- if ((stipple != None) && (polyPtr->fillGC != None)) {
+ if ((stipple != None) && (polyPtr->fillGC != NULL)) {
Tk_TSOffset *tsoffset = &polyPtr->tsoffset;
int w = 0, h = 0;
int flags = tsoffset->flags;
@@ -973,11 +973,11 @@ DisplayPolygon(
}
numPoints = polyPtr->smooth->coordProc(canvas, polyPtr->coordPtr,
polyPtr->numPoints, polyPtr->splineSteps, pointPtr, NULL);
- if (polyPtr->fillGC != None) {
+ if (polyPtr->fillGC != NULL) {
XFillPolygon(display, drawable, polyPtr->fillGC, pointPtr,
numPoints, Complex, CoordModeOrigin);
}
- if (polyPtr->outline.gc != None) {
+ if (polyPtr->outline.gc != NULL) {
XDrawLines(display, drawable, polyPtr->outline.gc, pointPtr,
numPoints, CoordModeOrigin);
}
@@ -986,7 +986,7 @@ DisplayPolygon(
}
}
Tk_ResetOutlineGC(canvas, itemPtr, &polyPtr->outline);
- if ((stipple != None) && (polyPtr->fillGC != None)) {
+ if ((stipple != None) && (polyPtr->fillGC != NULL)) {
XSetTSOrigin(display, polyPtr->fillGC, 0, 0);
}
}
@@ -1299,7 +1299,7 @@ PolygonToPoint(
if (bestDist <= 0.0) {
goto donepoint;
}
- if ((polyPtr->outline.gc != None) && (polyPtr->joinStyle == JoinRound)) {
+ if ((polyPtr->outline.gc != NULL) && (polyPtr->joinStyle == JoinRound)) {
dist = bestDist - radius;
if (dist <= 0.0) {
bestDist = 0.0;
@@ -1309,7 +1309,7 @@ PolygonToPoint(
}
}
- if ((polyPtr->outline.gc == None) || (width <= 1)) {
+ if ((polyPtr->outline.gc == NULL) || (width <= 1)) {
goto donepoint;
}
@@ -1515,7 +1515,7 @@ PolygonToArea(
goto donearea;
}
- if (polyPtr->outline.gc == None) {
+ if (polyPtr->outline.gc == NULL) {
goto donearea;
}
diff --git a/generic/tkCanvText.c b/generic/tkCanvText.c
index 7c088b5..c918399 100644
--- a/generic/tkCanvText.c
+++ b/generic/tkCanvText.c
@@ -269,9 +269,9 @@ CreateText(
textPtr->textLayout = NULL;
textPtr->actualWidth = 0;
textPtr->drawOrigin[0] = textPtr->drawOrigin[1] = 0.0;
- textPtr->gc = None;
- textPtr->selTextGC = None;
- textPtr->cursorOffGC = None;
+ textPtr->gc = NULL;
+ textPtr->selTextGC = NULL;
+ textPtr->cursorOffGC = NULL;
textPtr->sine = 0.0;
textPtr->cosine = 1.0;
@@ -447,7 +447,7 @@ ConfigureText(
}
}
- newGC = newSelGC = None;
+ newGC = newSelGC = NULL;
if (textPtr->tkfont != NULL) {
gcValues.font = Tk_FontId(textPtr->tkfont);
mask = GCFont;
@@ -472,11 +472,11 @@ ConfigureText(
}
newSelGC = Tk_GetGC(tkwin, mask|GCForeground, &gcValues);
}
- if (textPtr->gc != None) {
+ if (textPtr->gc != NULL) {
Tk_FreeGC(Tk_Display(tkwin), textPtr->gc);
}
textPtr->gc = newGC;
- if (textPtr->selTextGC != None) {
+ if (textPtr->selTextGC != NULL) {
Tk_FreeGC(Tk_Display(tkwin), textPtr->selTextGC);
}
textPtr->selTextGC = newSelGC;
@@ -491,9 +491,9 @@ ConfigureText(
}
newGC = Tk_GetGC(tkwin, GCForeground, &gcValues);
} else {
- newGC = None;
+ newGC = NULL;
}
- if (textPtr->cursorOffGC != None) {
+ if (textPtr->cursorOffGC != NULL) {
Tk_FreeGC(Tk_Display(tkwin), textPtr->cursorOffGC);
}
textPtr->cursorOffGC = newGC;
@@ -592,13 +592,13 @@ DeleteText(
}
Tk_FreeTextLayout(textPtr->textLayout);
- if (textPtr->gc != None) {
+ if (textPtr->gc != NULL) {
Tk_FreeGC(display, textPtr->gc);
}
- if (textPtr->selTextGC != None) {
+ if (textPtr->selTextGC != NULL) {
Tk_FreeGC(display, textPtr->selTextGC);
}
- if (textPtr->cursorOffGC != None) {
+ if (textPtr->cursorOffGC != NULL) {
Tk_FreeGC(display, textPtr->cursorOffGC);
}
}
@@ -820,7 +820,7 @@ DisplayCanvText(
}
}
- if (textPtr->gc == None) {
+ if (textPtr->gc == NULL) {
return;
}
@@ -932,7 +932,7 @@ DisplayCanvText(
Tk_Fill3DPolygon(Tk_CanvasTkwin(canvas), drawable,
textInfoPtr->insertBorder, points, 4,
textInfoPtr->insertBorderWidth, TK_RELIEF_RAISED);
- } else if (textPtr->cursorOffGC != None) {
+ } else if (textPtr->cursorOffGC != NULL) {
/*
* Redraw the background over the area of the cursor, even
* though the cursor is turned off. This guarantees that the
diff --git a/generic/tkCanvUtil.c b/generic/tkCanvUtil.c
index 09ce98c..6ce671d 100644
--- a/generic/tkCanvUtil.c
+++ b/generic/tkCanvUtil.c
@@ -961,7 +961,7 @@ void
Tk_CreateOutline(
Tk_Outline *outline) /* Outline structure to be filled in. */
{
- outline->gc = None;
+ outline->gc = NULL;
outline->width = 1.0;
outline->activeWidth = 0.0;
outline->disabledWidth = 0.0;
@@ -1002,7 +1002,7 @@ Tk_DeleteOutline(
Display *display, /* Display containing window. */
Tk_Outline *outline)
{
- if (outline->gc != None) {
+ if (outline->gc != NULL) {
Tk_FreeGC(display, outline->gc);
}
if ((unsigned) ABS(outline->dash.number) > sizeof(char *)) {
diff --git a/generic/tkCanvas.c b/generic/tkCanvas.c
index 18585d2..f3778a6 100644
--- a/generic/tkCanvas.c
+++ b/generic/tkCanvas.c
@@ -625,7 +625,7 @@ Tk_CanvasObjCmd(
canvasPtr->highlightBgColorPtr = NULL;
canvasPtr->highlightColorPtr = NULL;
canvasPtr->inset = 0;
- canvasPtr->pixmapGC = None;
+ canvasPtr->pixmapGC = NULL;
canvasPtr->width = None;
canvasPtr->height = None;
canvasPtr->confine = 0;
@@ -671,7 +671,7 @@ Tk_CanvasObjCmd(
canvasPtr->scanYOrigin = 0;
canvasPtr->hotPtr = NULL;
canvasPtr->hotPrevPtr = NULL;
- canvasPtr->cursor = None;
+ canvasPtr->cursor = NULL;
canvasPtr->takeFocus = NULL;
canvasPtr->pixelsPerMM = WidthOfScreen(Tk_Screen(newWin));
canvasPtr->pixelsPerMM /= WidthMMOfScreen(Tk_Screen(newWin));
@@ -2135,7 +2135,7 @@ DestroyCanvas(
*/
Tcl_DeleteHashTable(&canvasPtr->idTable);
- if (canvasPtr->pixmapGC != None) {
+ if (canvasPtr->pixmapGC != NULL) {
Tk_FreeGC(canvasPtr->display, canvasPtr->pixmapGC);
}
expr = canvasPtr->bindTagExprs;
@@ -2209,7 +2209,7 @@ ConfigureCanvas(
gcValues.foreground = Tk_3DBorderColor(canvasPtr->bgBorder)->pixel;
newGC = Tk_GetGC(canvasPtr->tkwin,
GCFunction|GCGraphicsExposures|GCForeground, &gcValues);
- if (canvasPtr->pixmapGC != None) {
+ if (canvasPtr->pixmapGC != NULL) {
Tk_FreeGC(canvasPtr->display, canvasPtr->pixmapGC);
}
canvasPtr->pixmapGC = newGC;
@@ -2769,21 +2769,10 @@ DrawCanvas(
* colours and place them in the photo block. Perhaps we could
* just not bother with the alpha byte because we are using
* TK_PHOTO_COMPOSITE_SET later?
- * ***Windows: We have to swap the red and blue values. The
- * XImage storage is B - G - R - A which becomes a 32bit ARGB
- * quad. However the visual mask is a 32bit ABGR quad. And
- * Tk_PhotoPutBlock() wants R-G-B-A which is a 32bit ABGR quad.
- * If the visual mask was correct there would be no need to
- * swap anything here.
*/
-#ifdef _WIN32
-#define R_OFFSET 2
-#define B_OFFSET 0
-#else
#define R_OFFSET 0
#define B_OFFSET 2
-#endif
blockPtr.pixelPtr[blockPtr.pitch * y + blockPtr.pixelSize * x + R_OFFSET] =
(unsigned char)((pixel & visualPtr->red_mask) >> rshift);
blockPtr.pixelPtr[blockPtr.pitch * y + blockPtr.pixelSize * x +1] =
diff --git a/generic/tkCanvas.h b/generic/tkCanvas.h
index b8b1b46..e2221a8 100644
--- a/generic/tkCanvas.h
+++ b/generic/tkCanvas.h
@@ -206,7 +206,7 @@ typedef struct TkCanvas {
* Miscellaneous information:
*/
- Tk_Cursor cursor; /* Current cursor for window, or None. */
+ Tk_Cursor cursor; /* Current cursor for window, or NULL. */
char *takeFocus; /* Value of -takefocus option; not used in the
* C code, but used by keyboard traversal
* scripts. Malloc'ed, but may be NULL. */
diff --git a/generic/tkColor.c b/generic/tkColor.c
index 9d5e157..3a82545 100644
--- a/generic/tkColor.c
+++ b/generic/tkColor.c
@@ -245,7 +245,7 @@ Tk_GetColor(
*/
tkColPtr->magic = COLOR_MAGIC;
- tkColPtr->gc = None;
+ tkColPtr->gc = NULL;
tkColPtr->screen = Tk_Screen(tkwin);
tkColPtr->colormap = Tk_Colormap(tkwin);
tkColPtr->visual = Tk_Visual(tkwin);
@@ -326,7 +326,7 @@ Tk_GetColorByValue(
tkColPtr = TkpGetColorByValue(tkwin, colorPtr);
tkColPtr->magic = COLOR_MAGIC;
- tkColPtr->gc = None;
+ tkColPtr->gc = NULL;
tkColPtr->screen = Tk_Screen(tkwin);
tkColPtr->colormap = valueKey.colormap;
tkColPtr->visual = Tk_Visual(tkwin);
@@ -436,7 +436,7 @@ Tk_GCForColor(
Tcl_Panic("Tk_GCForColor called with bogus color");
}
- if (tkColPtr->gc == None) {
+ if (tkColPtr->gc == NULL) {
gcValues.foreground = tkColPtr->color.pixel;
tkColPtr->gc = XCreateGC(DisplayOfScreen(tkColPtr->screen), drawable,
GCForeground, &gcValues);
@@ -490,9 +490,9 @@ Tk_FreeColor(
* longer any objects referencing it.
*/
- if (tkColPtr->gc != None) {
+ if (tkColPtr->gc != NULL) {
XFreeGC(DisplayOfScreen(screen), tkColPtr->gc);
- tkColPtr->gc = None;
+ tkColPtr->gc = NULL;
}
TkpFreeColor(tkColPtr);
diff --git a/generic/tkColor.h b/generic/tkColor.h
index d5bde9d..bcd71fe 100644
--- a/generic/tkColor.h
+++ b/generic/tkColor.h
@@ -32,7 +32,7 @@ typedef struct TkColor {
* COLOR_MAGIC. */
GC gc; /* Simple gc with this color as foreground
* color and all other fields defaulted. May
- * be None. */
+ * be NULL. */
Screen *screen; /* Screen where this color is valid. Used to
* delete it, and to find its display. */
Colormap colormap; /* Colormap from which this entry was
diff --git a/generic/tkConfig.c b/generic/tkConfig.c
index 46300d3..b9499e5 100644
--- a/generic/tkConfig.c
+++ b/generic/tkConfig.c
@@ -799,11 +799,11 @@ DoObjConfig(
Tk_Cursor newCursor;
if (nullOK && ObjectIsEmpty(valuePtr)) {
- newCursor = None;
+ newCursor = NULL;
valuePtr = NULL;
} else {
newCursor = Tk_AllocCursorFromObj(interp, tkwin, valuePtr);
- if (newCursor == None) {
+ if (newCursor == NULL) {
return TCL_ERROR;
}
}
@@ -861,7 +861,7 @@ DoObjConfig(
if (nullOK && ObjectIsEmpty(valuePtr)) {
valuePtr = NULL;
- newWin = None;
+ newWin = NULL;
} else {
if (TkGetWindowFromObj(interp, tkwin, valuePtr,
&newWin) != TCL_OK) {
@@ -1663,9 +1663,9 @@ FreeResources(
break;
case TK_OPTION_CURSOR:
if (internalFormExists) {
- if (*((Tk_Cursor *) internalPtr) != None) {
+ if (*((Tk_Cursor *) internalPtr) != NULL) {
Tk_FreeCursor(Tk_Display(tkwin), *((Tk_Cursor *) internalPtr));
- *((Tk_Cursor *) internalPtr) = None;
+ *((Tk_Cursor *) internalPtr) = NULL;
}
} else if (objPtr != NULL) {
Tk_FreeCursorFromObj(tkwin, objPtr);
@@ -1936,7 +1936,7 @@ GetObjectForOption(
case TK_OPTION_CURSOR: {
Tk_Cursor cursor = *((Tk_Cursor *) internalPtr);
- if (cursor != None) {
+ if (cursor != NULL) {
objPtr = Tcl_NewStringObj(
Tk_NameOfCursor(Tk_Display(tkwin), cursor), -1);
}
diff --git a/generic/tkCursor.c b/generic/tkCursor.c
index afdf6dd..76bbc89 100644
--- a/generic/tkCursor.c
+++ b/generic/tkCursor.c
@@ -150,7 +150,7 @@ Tk_AllocCursorFromObj(
cursorPtr = TkcGetCursor(interp, tkwin, Tcl_GetString(objPtr));
objPtr->internalRep.twoPtrValue.ptr1 = cursorPtr;
if (cursorPtr == NULL) {
- return None;
+ return NULL;
}
cursorPtr->objRefCount++;
return cursorPtr->cursor;
@@ -190,7 +190,7 @@ Tk_GetCursor(
TkCursor *cursorPtr = TkcGetCursor(interp, tkwin, string);
if (cursorPtr == NULL) {
- return None;
+ return NULL;
}
return cursorPtr->cursor;
}
@@ -388,7 +388,7 @@ Tk_GetCursorFromData(
error:
Tcl_DeleteHashEntry(dataHashPtr);
- return None;
+ return NULL;
}
/*
diff --git a/generic/tkEntry.c b/generic/tkEntry.c
index 8a69010..7e94d9b 100644
--- a/generic/tkEntry.c
+++ b/generic/tkEntry.c
@@ -536,20 +536,20 @@ Tk_EntryObjCmd(
entryPtr->selectFirst = -1;
entryPtr->selectLast = -1;
- entryPtr->cursor = None;
+ entryPtr->cursor = NULL;
entryPtr->exportSelection = 1;
entryPtr->justify = TK_JUSTIFY_LEFT;
entryPtr->relief = TK_RELIEF_FLAT;
entryPtr->state = STATE_NORMAL;
entryPtr->displayString = entryPtr->string;
entryPtr->inset = XPAD;
- entryPtr->textGC = None;
- entryPtr->selTextGC = None;
- entryPtr->highlightGC = None;
+ entryPtr->textGC = NULL;
+ entryPtr->selTextGC = NULL;
+ entryPtr->highlightGC = NULL;
entryPtr->avgWidth = 1;
entryPtr->validate = VALIDATE_NONE;
- entryPtr->placeholderGC = None;
+ entryPtr->placeholderGC = NULL;
/*
* Keep a hold of the associated tkwin until we destroy the entry,
@@ -1047,10 +1047,10 @@ DestroyEntry(
EntryTextVarProc, entryPtr);
entryPtr->flags &= ~ENTRY_VAR_TRACED;
}
- if (entryPtr->textGC != None) {
+ if (entryPtr->textGC != NULL) {
Tk_FreeGC(entryPtr->display, entryPtr->textGC);
}
- if (entryPtr->selTextGC != None) {
+ if (entryPtr->selTextGC != NULL) {
Tk_FreeGC(entryPtr->display, entryPtr->selTextGC);
}
Tcl_DeleteTimerHandler(entryPtr->insertBlinkHandler);
@@ -1446,7 +1446,7 @@ EntryWorldChanged(
ClientData instanceData) /* Information about widget. */
{
XGCValues gcValues;
- GC gc = None;
+ GC gc = NULL;
unsigned long mask;
Tk_3DBorder border;
XColor *colorPtr;
@@ -1498,7 +1498,7 @@ EntryWorldChanged(
gcValues.graphics_exposures = False;
mask = GCForeground | GCFont | GCGraphicsExposures;
gc = Tk_GetGC(entryPtr->tkwin, mask, &gcValues);
- if (entryPtr->textGC != None) {
+ if (entryPtr->textGC != NULL) {
Tk_FreeGC(entryPtr->display, entryPtr->textGC);
}
entryPtr->textGC = gc;
@@ -1508,7 +1508,7 @@ EntryWorldChanged(
}
mask = GCForeground | GCFont | GCGraphicsExposures;
gc = Tk_GetGC(entryPtr->tkwin, mask, &gcValues);
- if (entryPtr->placeholderGC != None) {
+ if (entryPtr->placeholderGC != NULL) {
Tk_FreeGC(entryPtr->display, entryPtr->placeholderGC);
}
entryPtr->placeholderGC = gc;
@@ -1521,7 +1521,7 @@ EntryWorldChanged(
gcValues.font = Tk_FontId(entryPtr->tkfont);
mask = GCForeground | GCFont;
gc = Tk_GetGC(entryPtr->tkwin, mask, &gcValues);
- if (entryPtr->selTextGC != None) {
+ if (entryPtr->selTextGC != NULL) {
Tk_FreeGC(entryPtr->display, entryPtr->selTextGC);
}
entryPtr->selTextGC = gc;
@@ -2541,9 +2541,9 @@ EntryEventProc(
} else if ((elem == SEL_BUTTONDOWN) || (elem == SEL_BUTTONUP)) {
cursor = sbPtr->bCursor;
} else {
- cursor = None;
+ cursor = NULL;
}
- if (cursor != None) {
+ if (cursor != NULL) {
Tk_DefineCursor(entryPtr->tkwin, cursor);
} else {
Tk_UndefineCursor(entryPtr->tkwin);
@@ -3717,22 +3717,22 @@ Tk_SpinboxObjCmd(
entryPtr->selectFirst = -1;
entryPtr->selectLast = -1;
- entryPtr->cursor = None;
+ entryPtr->cursor = NULL;
entryPtr->exportSelection = 1;
entryPtr->justify = TK_JUSTIFY_LEFT;
entryPtr->relief = TK_RELIEF_FLAT;
entryPtr->state = STATE_NORMAL;
entryPtr->displayString = entryPtr->string;
entryPtr->inset = XPAD;
- entryPtr->textGC = None;
- entryPtr->selTextGC = None;
- entryPtr->highlightGC = None;
+ entryPtr->textGC = NULL;
+ entryPtr->selTextGC = NULL;
+ entryPtr->highlightGC = NULL;
entryPtr->avgWidth = 1;
entryPtr->validate = VALIDATE_NONE;
sbPtr->selElement = SEL_NONE;
sbPtr->curElement = SEL_NONE;
- sbPtr->bCursor = None;
+ sbPtr->bCursor = NULL;
sbPtr->repeatDelay = 400;
sbPtr->repeatInterval = 100;
sbPtr->fromValue = 0.0;
@@ -3742,7 +3742,7 @@ Tk_SpinboxObjCmd(
sbPtr->bdRelief = TK_RELIEF_FLAT;
sbPtr->buRelief = TK_RELIEF_FLAT;
- entryPtr->placeholderGC = None;
+ entryPtr->placeholderGC = NULL;
/*
* Keep a hold of the associated tkwin until we destroy the spinbox,
diff --git a/generic/tkEntry.h b/generic/tkEntry.h
index e74b52b..c81563c 100644
--- a/generic/tkEntry.h
+++ b/generic/tkEntry.h
@@ -82,7 +82,7 @@ typedef struct {
* in readonly state, plus used for
* background. */
int borderWidth; /* Width of 3-D border around window. */
- Tk_Cursor cursor; /* Current cursor for window, or None. */
+ Tk_Cursor cursor; /* Current cursor for window, or NULL. */
int exportSelection; /* Non-zero means tie internal entry selection
* to X selection. */
Tk_Font tkfont; /* Information about text font, or NULL. */
@@ -205,7 +205,7 @@ typedef struct {
Tk_3DBorder activeBorder; /* Used for drawing border around active
* buttons. */
Tk_3DBorder buttonBorder; /* Used for drawing border around buttons. */
- Tk_Cursor bCursor; /* cursor for buttons, or None. */
+ Tk_Cursor bCursor; /* cursor for buttons, or NULL. */
int bdRelief; /* 3-D effect: TK_RELIEF_RAISED, etc. */
int buRelief; /* 3-D effect: TK_RELIEF_RAISED, etc. */
char *command; /* Command to invoke for spin buttons. NULL
diff --git a/generic/tkEvent.c b/generic/tkEvent.c
index d058e7c..891f667 100644
--- a/generic/tkEvent.c
+++ b/generic/tkEvent.c
@@ -1368,7 +1368,7 @@ Tk_HandleEvent(
* handle CreateNotify events, so we gotta pass 'em through.
*/
- if ((ip.winPtr != None)
+ if ((ip.winPtr != NULL)
&& ((mask != SubstructureNotifyMask)
|| (eventPtr->type == CreateNotify))) {
TkBindEventProc(winPtr, eventPtr);
@@ -1439,7 +1439,7 @@ TkEventDeadWindow(
ipPtr->nextHandler = NULL;
}
if (ipPtr->winPtr == winPtr) {
- ipPtr->winPtr = None;
+ ipPtr->winPtr = NULL;
}
}
ckfree(handlerPtr);
diff --git a/generic/tkFocus.c b/generic/tkFocus.c
index 60f631d..c621bf9 100644
--- a/generic/tkFocus.c
+++ b/generic/tkFocus.c
@@ -551,12 +551,17 @@ TkSetFocusWin(
return;
}
+ /*
+ * Get the current focus window with the same display and application
+ * as winPtr.
+ */
+
displayFocusPtr = FindDisplayFocusInfo(winPtr->mainPtr, winPtr->dispPtr);
/*
- * If force is set, we should make sure we grab the focus regardless of
- * the current focus window since under Windows, we may need to take
- * control away from another application.
+ * Do nothing if the window already has focus and force is not set. If
+ * force is set, we need to grab the focus, since under Windows or macOS
+ * this may involve taking control away from another application.
*/
if (winPtr == displayFocusPtr->focusWinPtr && !force) {
@@ -564,14 +569,15 @@ TkSetFocusWin(
}
/*
- * Find the top-level window for winPtr, then find (or create) a record
- * for the top-level. Also see whether winPtr and all its ancestors are
+ * Find the toplevel window for winPtr, then find (or create) a record
+ * for the toplevel. Also see whether winPtr and all its ancestors are
* mapped.
*/
allMapped = 1;
for (topLevelPtr = winPtr; ; topLevelPtr = topLevelPtr->parentPtr) {
if (topLevelPtr == NULL) {
+
/*
* The window is being deleted. No point in worrying about giving
* it the focus.
@@ -588,11 +594,11 @@ TkSetFocusWin(
}
/*
- * If the new focus window isn't mapped, then we can't focus on it (X will
- * generate an error, for example). Instead, create an event handler that
- * will set the focus to this window once it gets mapped. At the same
- * time, delete any old handler that might be around; it's no longer
- * relevant.
+ * If any ancestor of the new focus window isn't mapped, then we can't set
+ * focus for it (X will generate an error, for example). Instead, create
+ * an event handler that will set the focus to this window once it gets
+ * mapped. At the same time, delete any old handler that might be around;
+ * it's no longer relevant.
*/
if (displayFocusPtr->focusOnMapPtr != NULL) {
@@ -623,30 +629,38 @@ TkSetFocusWin(
}
tlFocusPtr->focusWinPtr = winPtr;
- /*
- * Reset the window system's focus window and generate focus events, with
- * two special cases:
- *
- * 1. If the application is embedded and doesn't currently have the focus,
- * don't set the focus directly. Instead, see if the embedding code can
- * claim the focus from the enclosing container.
- * 2. Otherwise, if the application doesn't currently have the focus,
- * don't change the window system's focus unless it was already in this
- * application or "force" was specified.
- */
+ if (topLevelPtr->flags & TK_EMBEDDED) {
+
+ /*
+ * We are assigning focus to an embedded toplevel. The platform
+ * specific function TkpClaimFocus needs to handle the job of
+ * assigning focus to the container, since we have no way to find the
+ * contaiuner.
+ */
- if ((topLevelPtr->flags & TK_EMBEDDED)
- && (displayFocusPtr->focusWinPtr == NULL)) {
TkpClaimFocus(topLevelPtr, force);
} else if ((displayFocusPtr->focusWinPtr != NULL) || force) {
+
/*
- * Generate events to shift focus between Tk windows. We do this
- * regardless of what TkpChangeFocus does with the real X focus so
- * that Tk widgets track focus commands when there is no window
- * manager. GenerateFocusEvents will set up a serial number marker so
- * we discard focus events that are triggered by the ChangeFocus.
+ * If we are forcing removal of focus from a container hosting a
+ * toplevel from a different application, clear the focus in that
+ * application.
*/
+
+ if (force) {
+ TkWindow *focusPtr = winPtr->dispPtr->focusPtr;
+ if (focusPtr && focusPtr->mainPtr != winPtr->mainPtr) {
+ DisplayFocusInfo *displayFocusPtr2 = FindDisplayFocusInfo(
+ focusPtr->mainPtr, focusPtr->dispPtr);
+ displayFocusPtr2->focusWinPtr = NULL;
+ }
+ }
+ /*
+ * Call the platform specific function TkpChangeFocus to move the
+ * window manager's focus to a new toplevel.
+ */
+
serial = TkpChangeFocus(TkpGetWrapperWindow(topLevelPtr), force);
if (serial != 0) {
displayFocusPtr->focusSerial = serial;
diff --git a/generic/tkFrame.c b/generic/tkFrame.c
index 53c019c..392799e 100644
--- a/generic/tkFrame.c
+++ b/generic/tkFrame.c
@@ -663,13 +663,13 @@ CreateFrame(
framePtr->type = type;
framePtr->colormap = colormap;
framePtr->relief = TK_RELIEF_FLAT;
- framePtr->cursor = None;
+ framePtr->cursor = NULL;
if (framePtr->type == TYPE_LABELFRAME) {
Labelframe *labelframePtr = (Labelframe *) framePtr;
labelframePtr->labelAnchor = LABELANCHOR_NW;
- labelframePtr->textGC = None;
+ labelframePtr->textGC = NULL;
}
/*
@@ -866,7 +866,7 @@ DestroyFrame(
if (framePtr->type == TYPE_LABELFRAME) {
Tk_FreeTextLayout(labelframePtr->textLayout);
- if (labelframePtr->textGC != None) {
+ if (labelframePtr->textGC != NULL) {
Tk_FreeGC(framePtr->display, labelframePtr->textGC);
}
}
@@ -1122,7 +1122,7 @@ FrameWorldChanged(
gcValues.graphics_exposures = False;
gc = Tk_GetGC(tkwin, GCForeground | GCFont | GCGraphicsExposures,
&gcValues);
- if (labelframePtr->textGC != None) {
+ if (labelframePtr->textGC != NULL) {
Tk_FreeGC(framePtr->display, labelframePtr->textGC);
}
labelframePtr->textGC = gc;
diff --git a/generic/tkGrab.c b/generic/tkGrab.c
index c37b6be..ff5d083 100644
--- a/generic/tkGrab.c
+++ b/generic/tkGrab.c
@@ -426,12 +426,7 @@ Tk_Grab(
}
Tk_MakeWindowExist(tkwin);
-#ifndef MAC_OSX_TK
- if (!grabGlobal)
-#else
- if (0)
-#endif /* MAC_OSX_TK */
- {
+ if (!grabGlobal) {
Window dummy1, dummy2;
int dummy3, dummy4, dummy5, dummy6;
unsigned int state;
diff --git a/generic/tkImage.c b/generic/tkImage.c
index 359d6c6..32e09c0 100644
--- a/generic/tkImage.c
+++ b/generic/tkImage.c
@@ -775,7 +775,7 @@ Tk_PostscriptImage(
gcValues.foreground = WhitePixelOfScreen(Tk_Screen(tkwin));
newGC = Tk_GetGC(tkwin, GCForeground, &gcValues);
- if (newGC != None) {
+ if (newGC != NULL) {
XFillRectangle(Tk_Display(tkwin), pmap, newGC, 0, 0,
(unsigned) width, (unsigned) height);
Tk_FreeGC(Tk_Display(tkwin), newGC);
diff --git a/generic/tkImgBmap.c b/generic/tkImgBmap.c
index 80b1c9c..a3a94f9 100644
--- a/generic/tkImgBmap.c
+++ b/generic/tkImgBmap.c
@@ -427,9 +427,9 @@ ImgBmapConfigureInstance(
}
gc = Tk_GetGC(instancePtr->tkwin, mask, &gcValues);
} else {
- gc = None;
+ gc = NULL;
}
- if (instancePtr->gc != None) {
+ if (instancePtr->gc != NULL) {
Tk_FreeGC(Tk_Display(instancePtr->tkwin), instancePtr->gc);
}
instancePtr->gc = gc;
@@ -441,10 +441,10 @@ ImgBmapConfigureInstance(
* it clear that this instance cannot be displayed. Then report the error.
*/
- if (instancePtr->gc != None) {
+ if (instancePtr->gc != NULL) {
Tk_FreeGC(Tk_Display(instancePtr->tkwin), instancePtr->gc);
}
- instancePtr->gc = None;
+ instancePtr->gc = NULL;
Tcl_AppendObjToErrorInfo(masterPtr->interp, Tcl_ObjPrintf(
"\n (while configuring image \"%s\")", Tk_NameOfImage(
masterPtr->tkMaster)));
@@ -848,7 +848,7 @@ ImgBmapGet(
instancePtr->bg = NULL;
instancePtr->bitmap = None;
instancePtr->mask = None;
- instancePtr->gc = None;
+ instancePtr->gc = NULL;
instancePtr->nextPtr = masterPtr->instancePtr;
masterPtr->instancePtr = instancePtr;
ImgBmapConfigureInstance(instancePtr);
@@ -902,7 +902,7 @@ ImgBmapDisplay(
* creating the image instance so it can't be displayed.
*/
- if (instancePtr->gc == None) {
+ if (instancePtr->gc == NULL) {
return;
}
@@ -972,7 +972,7 @@ ImgBmapFree(
if (instancePtr->mask != None) {
Tk_FreePixmap(display, instancePtr->mask);
}
- if (instancePtr->gc != None) {
+ if (instancePtr->gc != NULL) {
Tk_FreeGC(display, instancePtr->gc);
}
if (instancePtr->masterPtr->instancePtr == instancePtr) {
diff --git a/generic/tkImgGIF.c b/generic/tkImgGIF.c
index 5c29622..e3fe8f6 100644
--- a/generic/tkImgGIF.c
+++ b/generic/tkImgGIF.c
@@ -1364,6 +1364,7 @@ ReadImage(
}
pixelPtr = imagePtr + (ypos) * len * ((transparent>=0)?4:3);
}
+
/*
* Now read until the final zero byte.
* It was observed that there might be 1 length blocks
diff --git a/generic/tkImgPhInstance.c b/generic/tkImgPhInstance.c
index 1dc8840..f67ab36 100644
--- a/generic/tkImgPhInstance.c
+++ b/generic/tkImgPhInstance.c
@@ -1589,7 +1589,7 @@ TkImgDisposeInstance(
if (instancePtr->pixels != None) {
Tk_FreePixmap(instancePtr->display, instancePtr->pixels);
}
- if (instancePtr->gc != None) {
+ if (instancePtr->gc != NULL) {
Tk_FreeGC(instancePtr->display, instancePtr->gc);
}
if (instancePtr->imagePtr != NULL) {
diff --git a/generic/tkInt.decls b/generic/tkInt.decls
index 04eecf6..3a3cbc7 100644
--- a/generic/tkInt.decls
+++ b/generic/tkInt.decls
@@ -1016,7 +1016,7 @@ declare 47 aqua {
Tk_Window TkMacOSXGetCapture(void)
}
declare 49 aqua {
- Window TkGetTransientMaster(TkWindow *winPtr)
+ Tk_Window TkGetTransientMaster(TkWindow *winPtr)
}
declare 50 aqua {
int TkGenerateButtonEvent(int x, int y, Window window, unsigned int state)
diff --git a/generic/tkIntPlatDecls.h b/generic/tkIntPlatDecls.h
index 9bc76c0..4162396 100644
--- a/generic/tkIntPlatDecls.h
+++ b/generic/tkIntPlatDecls.h
@@ -243,7 +243,7 @@ EXTERN int TkpIsWindowFloating(void *window);
EXTERN Tk_Window TkMacOSXGetCapture(void);
/* Slot 48 is reserved */
/* 49 */
-EXTERN Window TkGetTransientMaster(TkWindow *winPtr);
+EXTERN Tk_Window TkGetTransientMaster(TkWindow *winPtr);
/* 50 */
EXTERN int TkGenerateButtonEvent(int x, int y, Window window,
unsigned int state);
@@ -392,7 +392,7 @@ typedef struct TkIntPlatStubs {
int (*tkpIsWindowFloating) (void *window); /* 46 */
Tk_Window (*tkMacOSXGetCapture) (void); /* 47 */
void (*reserved48)(void);
- Window (*tkGetTransientMaster) (TkWindow *winPtr); /* 49 */
+ Tk_Window (*tkGetTransientMaster) (TkWindow *winPtr); /* 49 */
int (*tkGenerateButtonEvent) (int x, int y, Window window, unsigned int state); /* 50 */
void (*tkGenWMDestroyEvent) (Tk_Window tkwin); /* 51 */
void (*tkMacOSXSetDrawingEnabled) (TkWindow *winPtr, int flag); /* 52 */
diff --git a/generic/tkListbox.c b/generic/tkListbox.c
index b3b8ce7..3a0237c 100644
--- a/generic/tkListbox.c
+++ b/generic/tkListbox.c
@@ -542,13 +542,13 @@ Tk_ListboxObjCmd(
listPtr->itemAttrTable = ckalloc(sizeof(Tcl_HashTable));
Tcl_InitHashTable(listPtr->itemAttrTable, TCL_ONE_WORD_KEYS);
listPtr->relief = TK_RELIEF_RAISED;
- listPtr->textGC = None;
- listPtr->selFgColorPtr = None;
- listPtr->selTextGC = None;
+ listPtr->textGC = NULL;
+ listPtr->selFgColorPtr = NULL;
+ listPtr->selTextGC = NULL;
listPtr->fullLines = 1;
listPtr->xScrollUnit = 1;
listPtr->exportSelection = 1;
- listPtr->cursor = None;
+ listPtr->cursor = NULL;
listPtr->state = STATE_NORMAL;
listPtr->gray = None;
listPtr->justify = TK_JUSTIFY_LEFT;
@@ -1489,10 +1489,10 @@ DestroyListbox(
* Tk_FreeOptions handle all the standard option-related stuff.
*/
- if (listPtr->textGC != None) {
+ if (listPtr->textGC != NULL) {
Tk_FreeGC(listPtr->display, listPtr->textGC);
}
- if (listPtr->selTextGC != None) {
+ if (listPtr->selTextGC != NULL) {
Tk_FreeGC(listPtr->display, listPtr->selTextGC);
}
if (listPtr->gray != None) {
@@ -1792,7 +1792,7 @@ ListboxWorldChanged(
gcValues.font = Tk_FontId(listPtr->tkfont);
gc = Tk_GetGC(listPtr->tkwin, mask, &gcValues);
- if (listPtr->textGC != None) {
+ if (listPtr->textGC != NULL) {
Tk_FreeGC(listPtr->display, listPtr->textGC);
}
listPtr->textGC = gc;
@@ -1803,7 +1803,7 @@ ListboxWorldChanged(
gcValues.font = Tk_FontId(listPtr->tkfont);
mask = GCForeground | GCFont;
gc = Tk_GetGC(listPtr->tkwin, mask, &gcValues);
- if (listPtr->selTextGC != None) {
+ if (listPtr->selTextGC != NULL) {
Tk_FreeGC(listPtr->display, listPtr->selTextGC);
}
listPtr->selTextGC = gc;
diff --git a/generic/tkMain.c b/generic/tkMain.c
index ffcaecf..eb311ff 100644
--- a/generic/tkMain.c
+++ b/generic/tkMain.c
@@ -37,7 +37,7 @@ extern int TkCygwinMainEx(int, char **, Tcl_AppInitProc *, Tcl_Interp *);
* The default prompt used when the user has not overridden it.
*/
-#define DEFAULT_PRIMARY_PROMPT "% "
+static const char DEFAULT_PRIMARY_PROMPT[] = "% ";
/*
* This file can be compiled on Windows in UNICODE mode, as well as
@@ -512,7 +512,7 @@ Prompt(
chan = Tcl_GetStdChannel(TCL_STDOUT);
if (chan != NULL) {
Tcl_WriteChars(chan, DEFAULT_PRIMARY_PROMPT,
- strlen(DEFAULT_PRIMARY_PROMPT));
+ sizeof(DEFAULT_PRIMARY_PROMPT) - 1);
}
}
} else {
diff --git a/generic/tkMenu.c b/generic/tkMenu.c
index 14d89cd..dd29d79 100644
--- a/generic/tkMenu.c
+++ b/generic/tkMenu.c
@@ -458,7 +458,7 @@ Tk_MenuObjCmd(
Tk_PathName(menuPtr->tkwin), MenuWidgetObjCmd, menuPtr,
MenuCmdDeletedProc);
menuPtr->active = -1;
- menuPtr->cursorPtr = None;
+ menuPtr->cursorPtr = NULL;
menuPtr->masterMenuPtr = menuPtr;
menuPtr->menuType = UNKNOWN_TYPE;
TkMenuInitializeDrawingFields(menuPtr);
@@ -873,32 +873,37 @@ MenuWidgetObjCmd(
break;
}
case MENU_POST: {
- int x, y;
+ int x, y, index = -1;
- if (objc != 4) {
- Tcl_WrongNumArgs(interp, 2, objv, "x y");
+ if (objc != 4 && objc != 5) {
+ Tcl_WrongNumArgs(interp, 2, objv, "x y ?index?");
goto error;
}
if ((Tcl_GetIntFromObj(interp, objv[2], &x) != TCL_OK)
|| (Tcl_GetIntFromObj(interp, objv[3], &y) != TCL_OK)) {
goto error;
}
+ if (objc == 5) {
+ if (TkGetMenuIndex(interp, menuPtr, objv[4], 0, &index) != TCL_OK) {
+ goto error;
+ }
+ }
/*
- * Tearoff menus are posted differently on Mac and Windows than
- * non-tearoffs. TkpPostMenu does not actually map the menu's window
- * on those platforms, and popup menus have to be handled specially.
- * Also, menubar menues are not intended to be posted (bug 1567681,
- * 2160206).
+ * Tearoff menus are the same as ordinary menus on the Mac and are
+ * posted differently on Windows than non-tearoffs. TkpPostMenu
+ * does not actually map the menu's window on those platforms, and
+ * popup menus have to be handled specially. Also, menubar menus are
+ * not intended to be posted (bug 1567681, 2160206).
*/
if (menuPtr->menuType == MENUBAR) {
Tcl_AppendResult(interp, "a menubar menu cannot be posted", NULL);
return TCL_ERROR;
} else if (menuPtr->menuType != TEAROFF_MENU) {
- result = TkpPostMenu(interp, menuPtr, x, y);
+ result = TkpPostMenu(interp, menuPtr, x, y, index);
} else {
- result = TkPostTearoffMenu(interp, menuPtr, x, y);
+ result = TkpPostTearoffMenu(interp, menuPtr, x, y, index);
}
break;
}
diff --git a/generic/tkMenu.h b/generic/tkMenu.h
index 6d51a72..8e25059 100644
--- a/generic/tkMenu.h
+++ b/generic/tkMenu.h
@@ -75,8 +75,8 @@ typedef struct TkMenuEntry {
* of character to underline (-1 means don't
* underline anything). */
Tcl_Obj *underlinePtr; /* Index of character to underline. */
- Tcl_Obj *bitmapPtr; /* Bitmap to display in menu entry, or None.
- * If not None then label is ignored. */
+ Tcl_Obj *bitmapPtr; /* Bitmap to display in menu entry, or NULL.
+ * If not NULL then label is ignored. */
Tcl_Obj *imagePtr; /* Name of image to display, or NULL. If not
* NULL, bitmap, text, and textVarName are
* ignored. */
@@ -175,7 +175,7 @@ typedef struct TkMenuEntry {
* NULL means use overall disabledGC from menu
* structure. See comments for disabledFg in
* menu structure for more information. */
- GC indicatorGC; /* For drawing indicators. None means use GC
+ GC indicatorGC; /* For drawing indicators. NULL means use GC
* from menu. */
/*
@@ -340,7 +340,7 @@ typedef struct TkMenu {
Tcl_Obj *takeFocusPtr; /* Value of -takefocus option; not used in the
* C code, but used by keyboard traversal
* scripts. Malloc'ed, but may be NULL. */
- Tcl_Obj *cursorPtr; /* Current cursor for window, or None. */
+ Tcl_Obj *cursorPtr; /* Current cursor for window, or NULL. */
Tcl_Obj *postCommandPtr; /* Used to detect cycles in cascade hierarchy
* trees when preprocessing postcommands on
* some platforms. See PostMenu for more
@@ -521,7 +521,7 @@ MODULE_SCOPE int TkPostCommand(TkMenu *menuPtr);
MODULE_SCOPE int TkPostSubmenu(Tcl_Interp *interp, TkMenu *menuPtr,
TkMenuEntry *mePtr);
MODULE_SCOPE int TkPostTearoffMenu(Tcl_Interp *interp, TkMenu *menuPtr,
- int x, int y);
+ int x, int y);
MODULE_SCOPE int TkPreprocessMenu(TkMenu *menuPtr);
MODULE_SCOPE void TkRecomputeMenu(TkMenu *menuPtr);
@@ -544,7 +544,9 @@ MODULE_SCOPE void TkpMenuInit(void);
MODULE_SCOPE int TkpMenuNewEntry(TkMenuEntry *mePtr);
MODULE_SCOPE int TkpNewMenu(TkMenu *menuPtr);
MODULE_SCOPE int TkpPostMenu(Tcl_Interp *interp, TkMenu *menuPtr,
- int x, int y);
+ int x, int y, int index);
+MODULE_SCOPE int TkpPostTearoffMenu(Tcl_Interp *interp, TkMenu *menuPtr,
+ int x, int y, int index);
MODULE_SCOPE void TkpSetWindowMenuBar(Tk_Window tkwin, TkMenu *menuPtr);
#endif /* _TKMENU */
diff --git a/generic/tkMenuDraw.c b/generic/tkMenuDraw.c
index 3f492db..bd00d38 100644
--- a/generic/tkMenuDraw.c
+++ b/generic/tkMenuDraw.c
@@ -43,12 +43,12 @@ void
TkMenuInitializeDrawingFields(
TkMenu *menuPtr) /* The menu we are initializing. */
{
- menuPtr->textGC = None;
+ menuPtr->textGC = NULL;
menuPtr->gray = None;
- menuPtr->disabledGC = None;
- menuPtr->activeGC = None;
- menuPtr->indicatorGC = None;
- menuPtr->disabledImageGC = None;
+ menuPtr->disabledGC = NULL;
+ menuPtr->activeGC = NULL;
+ menuPtr->indicatorGC = NULL;
+ menuPtr->disabledImageGC = NULL;
menuPtr->totalWidth = menuPtr->totalHeight = 0;
}
@@ -79,10 +79,10 @@ TkMenuInitializeEntryDrawingFields(
mePtr->y = 0;
mePtr->indicatorSpace = 0;
mePtr->labelWidth = 0;
- mePtr->textGC = None;
- mePtr->activeGC = None;
- mePtr->disabledGC = None;
- mePtr->indicatorGC = None;
+ mePtr->textGC = NULL;
+ mePtr->activeGC = NULL;
+ mePtr->disabledGC = NULL;
+ mePtr->indicatorGC = NULL;
}
/*
@@ -106,22 +106,22 @@ void
TkMenuFreeDrawOptions(
TkMenu *menuPtr)
{
- if (menuPtr->textGC != None) {
+ if (menuPtr->textGC != NULL) {
Tk_FreeGC(menuPtr->display, menuPtr->textGC);
}
- if (menuPtr->disabledImageGC != None) {
+ if (menuPtr->disabledImageGC != NULL) {
Tk_FreeGC(menuPtr->display, menuPtr->disabledImageGC);
}
if (menuPtr->gray != None) {
Tk_FreeBitmap(menuPtr->display, menuPtr->gray);
}
- if (menuPtr->disabledGC != None) {
+ if (menuPtr->disabledGC != NULL) {
Tk_FreeGC(menuPtr->display, menuPtr->disabledGC);
}
- if (menuPtr->activeGC != None) {
+ if (menuPtr->activeGC != NULL) {
Tk_FreeGC(menuPtr->display, menuPtr->activeGC);
}
- if (menuPtr->indicatorGC != None) {
+ if (menuPtr->indicatorGC != NULL) {
Tk_FreeGC(menuPtr->display, menuPtr->indicatorGC);
}
}
@@ -147,16 +147,16 @@ void
TkMenuEntryFreeDrawOptions(
TkMenuEntry *mePtr)
{
- if (mePtr->textGC != None) {
+ if (mePtr->textGC != NULL) {
Tk_FreeGC(mePtr->menuPtr->display, mePtr->textGC);
}
- if (mePtr->disabledGC != None) {
+ if (mePtr->disabledGC != NULL) {
Tk_FreeGC(mePtr->menuPtr->display, mePtr->disabledGC);
}
- if (mePtr->activeGC != None) {
+ if (mePtr->activeGC != NULL) {
Tk_FreeGC(mePtr->menuPtr->display, mePtr->activeGC);
}
- if (mePtr->indicatorGC != None) {
+ if (mePtr->indicatorGC != NULL) {
Tk_FreeGC(mePtr->menuPtr->display, mePtr->indicatorGC);
}
}
@@ -205,7 +205,7 @@ TkMenuConfigureDrawOptions(
gcValues.background = Tk_3DBorderColor(border)->pixel;
newGC = Tk_GetGC(menuPtr->tkwin, GCForeground|GCBackground|GCFont,
&gcValues);
- if (menuPtr->textGC != None) {
+ if (menuPtr->textGC != NULL) {
Tk_FreeGC(menuPtr->display, menuPtr->textGC);
}
menuPtr->textGC = newGC;
@@ -233,7 +233,7 @@ TkMenuConfigureDrawOptions(
}
}
newGC = Tk_GetGC(menuPtr->tkwin, mask, &gcValues);
- if (menuPtr->disabledGC != None) {
+ if (menuPtr->disabledGC != NULL) {
Tk_FreeGC(menuPtr->display, menuPtr->disabledGC);
}
menuPtr->disabledGC = newGC;
@@ -249,7 +249,7 @@ TkMenuConfigureDrawOptions(
newGC = Tk_GetGC(menuPtr->tkwin,
GCForeground|GCFillStyle|GCStipple, &gcValues);
}
- if (menuPtr->disabledImageGC != None) {
+ if (menuPtr->disabledImageGC != NULL) {
Tk_FreeGC(menuPtr->display, menuPtr->disabledImageGC);
}
menuPtr->disabledImageGC = newGC;
@@ -262,7 +262,7 @@ TkMenuConfigureDrawOptions(
gcValues.background = Tk_3DBorderColor(activeBorder)->pixel;
newGC = Tk_GetGC(menuPtr->tkwin, GCForeground|GCBackground|GCFont,
&gcValues);
- if (menuPtr->activeGC != None) {
+ if (menuPtr->activeGC != NULL) {
Tk_FreeGC(menuPtr->display, menuPtr->activeGC);
}
menuPtr->activeGC = newGC;
@@ -273,7 +273,7 @@ TkMenuConfigureDrawOptions(
gcValues.background = Tk_3DBorderColor(border)->pixel;
newGC = Tk_GetGC(menuPtr->tkwin, GCForeground|GCBackground|GCFont,
&gcValues);
- if (menuPtr->indicatorGC != None) {
+ if (menuPtr->indicatorGC != NULL) {
Tk_FreeGC(menuPtr->display, menuPtr->indicatorGC);
}
menuPtr->indicatorGC = newGC;
@@ -385,24 +385,24 @@ TkMenuConfigureEntryDrawOptions(
GCForeground|GCBackground|GCFont|GCGraphicsExposures,
&gcValues);
} else {
- newGC = None;
- newActiveGC = None;
- newDisabledGC = None;
- newIndicatorGC = None;
+ newGC = NULL;
+ newActiveGC = NULL;
+ newDisabledGC = NULL;
+ newIndicatorGC = NULL;
}
- if (mePtr->textGC != None) {
+ if (mePtr->textGC != NULL) {
Tk_FreeGC(menuPtr->display, mePtr->textGC);
}
mePtr->textGC = newGC;
- if (mePtr->activeGC != None) {
+ if (mePtr->activeGC != NULL) {
Tk_FreeGC(menuPtr->display, mePtr->activeGC);
}
mePtr->activeGC = newActiveGC;
- if (mePtr->disabledGC != None) {
+ if (mePtr->disabledGC != NULL) {
Tk_FreeGC(menuPtr->display, mePtr->disabledGC);
}
mePtr->disabledGC = newDisabledGC;
- if (mePtr->indicatorGC != None) {
+ if (mePtr->indicatorGC != NULL) {
Tk_FreeGC(menuPtr->display, mePtr->indicatorGC);
}
mePtr->indicatorGC = newIndicatorGC;
@@ -807,9 +807,8 @@ TkMenuImageProc(
*
* TkPostTearoffMenu --
*
- * Posts a menu on the screen. Used to post tearoff menus. On Unix, all
- * menus are posted this way. Adjusts the menu's position so that it fits
- * on the screen, and maps and raises the menu.
+ * Posts a tearoff menu on the screen. Adjusts the menu's position so
+ * that it fits on the screen, and maps and raises the menu.
*
* Results:
* Returns a standard Tcl Error.
@@ -827,64 +826,7 @@ TkPostTearoffMenu(
int x, int y) /* The root X,Y coordinates where we are
* posting */
{
- int vRootX, vRootY, vRootWidth, vRootHeight;
- int result;
-
- TkActivateMenuEntry(menuPtr, -1);
- TkRecomputeMenu(menuPtr);
- result = TkPostCommand(menuPtr);
- if (result != TCL_OK) {
- return result;
- }
-
- /*
- * The post commands could have deleted the menu, which means we are dead
- * and should go away.
- */
-
- if (menuPtr->tkwin == NULL) {
- return TCL_OK;
- }
-
- /*
- * Adjust the position of the menu if necessary to keep it visible on the
- * screen. There are two special tricks to make this work right:
- *
- * 1. If a virtual root window manager is being used then the coordinates
- * are in the virtual root window of menuPtr's parent; since the menu
- * uses override-redirect mode it will be in the *real* root window for
- * the screen, so we have to map the coordinates from the virtual root
- * (if any) to the real root. Can't get the virtual root from the menu
- * itself (it will never be seen by the wm) so use its parent instead
- * (it would be better to have an an option that names a window to use
- * for this...).
- * 2. The menu may not have been mapped yet, so its current size might be
- * the default 1x1. To compute how much space it needs, use its
- * requested size, not its actual size.
- */
-
- Tk_GetVRootGeometry(Tk_Parent(menuPtr->tkwin), &vRootX, &vRootY,
- &vRootWidth, &vRootHeight);
- vRootWidth -= Tk_ReqWidth(menuPtr->tkwin);
- if (x > vRootX + vRootWidth) {
- x = vRootX + vRootWidth;
- }
- if (x < vRootX) {
- x = vRootX;
- }
- vRootHeight -= Tk_ReqHeight(menuPtr->tkwin);
- if (y > vRootY + vRootHeight) {
- y = vRootY + vRootHeight;
- }
- if (y < vRootY) {
- y = vRootY;
- }
- Tk_MoveToplevelWindow(menuPtr->tkwin, x, y);
- if (!Tk_IsMapped(menuPtr->tkwin)) {
- Tk_MapWindow(menuPtr->tkwin);
- }
- TkWmRestackToplevel((TkWindow *) menuPtr->tkwin, Above, NULL);
- return TCL_OK;
+ return TkpPostTearoffMenu(interp, menuPtr, x, y, -1);
}
/*
diff --git a/generic/tkMenubutton.c b/generic/tkMenubutton.c
index 125fe72..fa5b63f 100644
--- a/generic/tkMenubutton.c
+++ b/generic/tkMenubutton.c
@@ -279,11 +279,11 @@ Tk_MenubuttonObjCmd(
mbPtr->normalFg = NULL;
mbPtr->activeFg = NULL;
mbPtr->disabledFg = NULL;
- mbPtr->normalTextGC = None;
- mbPtr->activeTextGC = None;
+ mbPtr->normalTextGC = NULL;
+ mbPtr->activeTextGC = NULL;
mbPtr->gray = None;
- mbPtr->disabledGC = None;
- mbPtr->stippleGC = None;
+ mbPtr->disabledGC = NULL;
+ mbPtr->stippleGC = NULL;
mbPtr->leftBearing = 0;
mbPtr->rightBearing = 0;
mbPtr->widthString = NULL;
@@ -300,7 +300,7 @@ Tk_MenubuttonObjCmd(
mbPtr->indicatorWidth = 0;
mbPtr->indicatorHeight = 0;
mbPtr->direction = DIRECTION_FLUSH;
- mbPtr->cursor = None;
+ mbPtr->cursor = NULL;
mbPtr->takeFocus = NULL;
mbPtr->flags = 0;
@@ -443,16 +443,16 @@ DestroyMenuButton(
if (mbPtr->image != NULL) {
Tk_FreeImage(mbPtr->image);
}
- if (mbPtr->normalTextGC != None) {
+ if (mbPtr->normalTextGC != NULL) {
Tk_FreeGC(mbPtr->display, mbPtr->normalTextGC);
}
- if (mbPtr->activeTextGC != None) {
+ if (mbPtr->activeTextGC != NULL) {
Tk_FreeGC(mbPtr->display, mbPtr->activeTextGC);
}
- if (mbPtr->disabledGC != None) {
+ if (mbPtr->disabledGC != NULL) {
Tk_FreeGC(mbPtr->display, mbPtr->disabledGC);
}
- if (mbPtr->stippleGC != None) {
+ if (mbPtr->stippleGC != NULL) {
Tk_FreeGC(mbPtr->display, mbPtr->stippleGC);
}
if (mbPtr->gray != None) {
@@ -690,7 +690,7 @@ TkMenuButtonWorldChanged(
gcValues.graphics_exposures = False;
mask = GCForeground | GCBackground | GCFont | GCGraphicsExposures;
gc = Tk_GetGC(mbPtr->tkwin, mask, &gcValues);
- if (mbPtr->normalTextGC != None) {
+ if (mbPtr->normalTextGC != NULL) {
Tk_FreeGC(mbPtr->display, mbPtr->normalTextGC);
}
mbPtr->normalTextGC = gc;
@@ -699,7 +699,7 @@ TkMenuButtonWorldChanged(
gcValues.background = Tk_3DBorderColor(mbPtr->activeBorder)->pixel;
mask = GCForeground | GCBackground | GCFont;
gc = Tk_GetGC(mbPtr->tkwin, mask, &gcValues);
- if (mbPtr->activeTextGC != None) {
+ if (mbPtr->activeTextGC != NULL) {
Tk_FreeGC(mbPtr->display, mbPtr->activeTextGC);
}
mbPtr->activeTextGC = gc;
@@ -710,7 +710,7 @@ TkMenuButtonWorldChanged(
* Create the GC that can be used for stippling
*/
- if (mbPtr->stippleGC == None) {
+ if (mbPtr->stippleGC == NULL) {
gcValues.foreground = gcValues.background;
mask = GCForeground;
if (mbPtr->gray == None) {
@@ -736,7 +736,7 @@ TkMenuButtonWorldChanged(
gcValues.foreground = gcValues.background;
}
gc = Tk_GetGC(mbPtr->tkwin, mask, &gcValues);
- if (mbPtr->disabledGC != None) {
+ if (mbPtr->disabledGC != NULL) {
Tk_FreeGC(mbPtr->display, mbPtr->disabledGC);
}
mbPtr->disabledGC = gc;
diff --git a/generic/tkMenubutton.h b/generic/tkMenubutton.h
index e8dc12f..1dbacb3 100644
--- a/generic/tkMenubutton.h
+++ b/generic/tkMenubutton.h
@@ -170,7 +170,7 @@ typedef struct {
* "left" and "right" will pop the menu left
* or right, and the active item will be next
* to the button. */
- Tk_Cursor cursor; /* Current cursor for window, or None. */
+ Tk_Cursor cursor; /* Current cursor for window, or NULL. */
char *takeFocus; /* Value of -takefocus option; not used in the
* C code, but used by keyboard traversal
* scripts. Malloc'ed, but may be NULL. */
diff --git a/generic/tkMessage.c b/generic/tkMessage.c
index c009fe7..306572e 100644
--- a/generic/tkMessage.c
+++ b/generic/tkMessage.c
@@ -256,11 +256,11 @@ Tk_MessageObjCmd(
MessageCmdDeletedProc);
msgPtr->optionTable = optionTable;
msgPtr->relief = TK_RELIEF_FLAT;
- msgPtr->textGC = None;
+ msgPtr->textGC = NULL;
msgPtr->anchor = TK_ANCHOR_CENTER;
msgPtr->aspect = 150;
msgPtr->justify = TK_JUSTIFY_LEFT;
- msgPtr->cursor = None;
+ msgPtr->cursor = NULL;
Tk_SetClass(msgPtr->tkwin, "Message");
Tk_SetClassProcs(msgPtr->tkwin, &messageClass, msgPtr);
@@ -398,7 +398,7 @@ DestroyMessage(
* Tk_FreeConfigOptions handle all the standard option-related stuff.
*/
- if (msgPtr->textGC != None) {
+ if (msgPtr->textGC != NULL) {
Tk_FreeGC(msgPtr->display, msgPtr->textGC);
}
if (msgPtr->textLayout != NULL) {
@@ -525,7 +525,7 @@ MessageWorldChanged(
ClientData instanceData) /* Information about widget. */
{
XGCValues gcValues;
- GC gc = None;
+ GC gc = NULL;
Tk_FontMetrics fm;
Message *msgPtr = instanceData;
@@ -536,7 +536,7 @@ MessageWorldChanged(
gcValues.font = Tk_FontId(msgPtr->tkfont);
gcValues.foreground = msgPtr->fgColorPtr->pixel;
gc = Tk_GetGC(msgPtr->tkwin, GCForeground | GCFont, &gcValues);
- if (msgPtr->textGC != None) {
+ if (msgPtr->textGC != NULL) {
Tk_FreeGC(msgPtr->display, msgPtr->textGC);
}
msgPtr->textGC = gc;
diff --git a/generic/tkOldConfig.c b/generic/tkOldConfig.c
index 4473a3e..d83c30b 100644
--- a/generic/tkOldConfig.c
+++ b/generic/tkOldConfig.c
@@ -481,16 +481,16 @@ DoConfig(
Tk_Cursor newCursor, oldCursor;
if (nullValue) {
- newCursor = None;
+ newCursor = NULL;
} else {
uid = valueIsUid ? (Tk_Uid) value : Tk_GetUid(value);
newCursor = Tk_GetCursor(interp, tkwin, uid);
- if (newCursor == None) {
+ if (newCursor == NULL) {
return TCL_ERROR;
}
}
oldCursor = *((Tk_Cursor *) ptr);
- if (oldCursor != None) {
+ if (oldCursor != NULL) {
Tk_FreeCursor(Tk_Display(tkwin), oldCursor);
}
*((Tk_Cursor *) ptr) = newCursor;
@@ -842,7 +842,7 @@ FormatConfigValue(
case TK_CONFIG_ACTIVE_CURSOR: {
Tk_Cursor cursor = *((Tk_Cursor *) ptr);
- if (cursor != None) {
+ if (cursor != NULL) {
result = Tk_NameOfCursor(Tk_Display(tkwin), cursor);
}
break;
@@ -1027,9 +1027,9 @@ Tk_FreeOptions(
break;
case TK_CONFIG_CURSOR:
case TK_CONFIG_ACTIVE_CURSOR:
- if (*((Tk_Cursor *) ptr) != None) {
+ if (*((Tk_Cursor *) ptr) != NULL) {
Tk_FreeCursor(display, *((Tk_Cursor *) ptr));
- *((Tk_Cursor *) ptr) = None;
+ *((Tk_Cursor *) ptr) = NULL;
}
}
}
diff --git a/generic/tkPanedWindow.c b/generic/tkPanedWindow.c
index c0bbf5f..faec67a 100644
--- a/generic/tkPanedWindow.c
+++ b/generic/tkPanedWindow.c
@@ -448,9 +448,9 @@ Tk_PanedWindowObjCmd(
pwPtr->optionTable = pwOpts->pwOptions;
pwPtr->slaveOpts = pwOpts->slaveOpts;
pwPtr->relief = TK_RELIEF_RAISED;
- pwPtr->gc = None;
- pwPtr->cursor = None;
- pwPtr->sashCursor = None;
+ pwPtr->gc = NULL;
+ pwPtr->cursor = NULL;
+ pwPtr->sashCursor = NULL;
/*
* Keep a hold of the associated tkwin until we destroy the widget,
@@ -862,7 +862,7 @@ ConfigureSlaves(
index = -1;
haveLoc = 0;
- if (options.after != None) {
+ if (options.after != NULL) {
tkwin = options.after;
haveLoc = 1;
for (i = 0; i < pwPtr->numSlaves; i++) {
@@ -871,7 +871,7 @@ ConfigureSlaves(
break;
}
}
- } else if (options.before != None) {
+ } else if (options.before != NULL) {
tkwin = options.before;
haveLoc = 1;
for (i = 0; i < pwPtr->numSlaves; i++) {
@@ -1304,7 +1304,7 @@ PanedWindowWorldChanged(
gcValues.background = Tk_3DBorderColor(pwPtr->background)->pixel;
newGC = Tk_GetGC(pwPtr->tkwin, GCBackground, &gcValues);
- if (pwPtr->gc != None) {
+ if (pwPtr->gc != NULL) {
Tk_FreeGC(pwPtr->display, pwPtr->gc);
}
pwPtr->gc = newGC;
@@ -2044,10 +2044,10 @@ Unlink(
for (i = 0; i < masterPtr->numSlaves; i++) {
if (masterPtr->slaves[i]->before == slavePtr->tkwin) {
- masterPtr->slaves[i]->before = None;
+ masterPtr->slaves[i]->before = NULL;
}
if (masterPtr->slaves[i]->after == slavePtr->tkwin) {
- masterPtr->slaves[i]->after = None;
+ masterPtr->slaves[i]->after = NULL;
}
}
diff --git a/generic/tkPlace.c b/generic/tkPlace.c
index b225e26..08d5c8e 100644
--- a/generic/tkPlace.c
+++ b/generic/tkPlace.c
@@ -395,7 +395,7 @@ CreateSlave(
slavePtr = ckalloc(sizeof(Slave));
memset(slavePtr, 0, sizeof(Slave));
slavePtr->tkwin = tkwin;
- slavePtr->inTkwin = None;
+ slavePtr->inTkwin = NULL;
slavePtr->anchor = TK_ANCHOR_NW;
slavePtr->borderMode = BM_INSIDE;
slavePtr->optionTable = table;
@@ -1185,6 +1185,12 @@ PlaceRequestProc(
if ((slavePtr->flags & (CHILD_WIDTH|CHILD_REL_WIDTH))
&& (slavePtr->flags & (CHILD_HEIGHT|CHILD_REL_HEIGHT))) {
+ /*
+ * Send a ConfigureNotify to indicate that the size change
+ * request was rejected.
+ */
+
+ TkDoConfigureNotify((TkWindow *)(slavePtr->tkwin));
return;
}
masterPtr = slavePtr->masterPtr;
diff --git a/generic/tkRectOval.c b/generic/tkRectOval.c
index 4d48fe7..359d3ef 100644
--- a/generic/tkRectOval.c
+++ b/generic/tkRectOval.c
@@ -258,7 +258,7 @@ CreateRectOval(
rectOvalPtr->fillStipple = None;
rectOvalPtr->activeFillStipple = None;
rectOvalPtr->disabledFillStipple = None;
- rectOvalPtr->fillGC = None;
+ rectOvalPtr->fillGC = NULL;
/*
* Process the arguments to fill in the item record.
@@ -466,9 +466,9 @@ ConfigureRectOval(
mask |= GCCapStyle;
newGC = Tk_GetGC(tkwin, mask, &gcValues);
} else {
- newGC = None;
+ newGC = NULL;
}
- if (rectOvalPtr->outline.gc != None) {
+ if (rectOvalPtr->outline.gc != NULL) {
Tk_FreeGC(Tk_Display(tkwin), rectOvalPtr->outline.gc);
}
rectOvalPtr->outline.gc = newGC;
@@ -500,7 +500,7 @@ ConfigureRectOval(
}
if (color == NULL) {
- newGC = None;
+ newGC = NULL;
} else {
gcValues.foreground = color->pixel;
if (stipple != None) {
@@ -515,14 +515,13 @@ ConfigureRectOval(
* Mac OS X CG drawing needs access to the outline linewidth even for
* fills (as linewidth controls antialiasing).
*/
-
- gcValues.line_width = rectOvalPtr->outline.gc != None ?
+ gcValues.line_width = rectOvalPtr->outline.gc != NULL ?
rectOvalPtr->outline.gc->line_width : 0;
mask |= GCLineWidth;
#endif
newGC = Tk_GetGC(tkwin, mask, &gcValues);
}
- if (rectOvalPtr->fillGC != None) {
+ if (rectOvalPtr->fillGC != NULL) {
Tk_FreeGC(Tk_Display(tkwin), rectOvalPtr->fillGC);
}
rectOvalPtr->fillGC = newGC;
@@ -595,7 +594,7 @@ DeleteRectOval(
if (rectOvalPtr->disabledFillStipple != None) {
Tk_FreeBitmap(display, rectOvalPtr->disabledFillStipple);
}
- if (rectOvalPtr->fillGC != None) {
+ if (rectOvalPtr->fillGC != NULL) {
Tk_FreeGC(display, rectOvalPtr->fillGC);
}
}
@@ -664,7 +663,7 @@ ComputeRectOvalBbox(
rectOvalPtr->bbox[0] = tmpX;
}
- if (rectOvalPtr->outline.gc == None) {
+ if (rectOvalPtr->outline.gc == NULL) {
/*
* The Win32 switch was added for 8.3 to solve a problem with ovals
* leaving traces on bottom and right of 1 pixel. This may not be the
@@ -878,7 +877,7 @@ DisplayRectOval(
}
}
- if (rectOvalPtr->fillGC != None) {
+ if (rectOvalPtr->fillGC != NULL) {
if (fillStipple != None) {
Tk_TSOffset *tsoffset;
int w = 0, h = 0;
@@ -922,7 +921,7 @@ DisplayRectOval(
}
}
- if (rectOvalPtr->outline.gc != None) {
+ if (rectOvalPtr->outline.gc != NULL) {
Tk_ChangeOutlineGC(canvas, itemPtr, &(rectOvalPtr->outline));
if (rectOvalPtr->header.typePtr == &tkRectangleType) {
XDrawRectangle(display, drawable, rectOvalPtr->outline.gc,
@@ -993,7 +992,7 @@ RectToPoint(
y1 = rectPtr->bbox[1];
x2 = rectPtr->bbox[2];
y2 = rectPtr->bbox[3];
- if (rectPtr->outline.gc != None) {
+ if (rectPtr->outline.gc != NULL) {
inc = width/2.0;
x1 -= inc;
y1 -= inc;
@@ -1009,7 +1008,7 @@ RectToPoint(
if ((pointPtr[0] >= x1) && (pointPtr[0] < x2)
&& (pointPtr[1] >= y1) && (pointPtr[1] < y2)) {
- if ((rectPtr->fillGC != None) || (rectPtr->outline.gc == None)) {
+ if ((rectPtr->fillGC != NULL) || (rectPtr->outline.gc == NULL)) {
return 0.0;
}
xDiff = pointPtr[0] - x1;
@@ -1105,8 +1104,8 @@ OvalToPoint(
}
- filled = ovalPtr->fillGC != None;
- if (ovalPtr->outline.gc == None) {
+ filled = ovalPtr->fillGC != NULL;
+ if (ovalPtr->outline.gc == NULL) {
width = 0.0;
filled = 1;
}
@@ -1161,7 +1160,7 @@ RectToArea(
}
halfWidth = width/2.0;
- if (rectPtr->outline.gc == None) {
+ if (rectPtr->outline.gc == NULL) {
halfWidth = 0.0;
}
@@ -1171,7 +1170,7 @@ RectToArea(
|| (areaPtr[1] >= (rectPtr->bbox[3] + halfWidth))) {
return -1;
}
- if ((rectPtr->fillGC == None) && (rectPtr->outline.gc != None)
+ if ((rectPtr->fillGC == NULL) && (rectPtr->outline.gc != NULL)
&& (areaPtr[0] >= (rectPtr->bbox[0] + halfWidth))
&& (areaPtr[1] >= (rectPtr->bbox[1] + halfWidth))
&& (areaPtr[2] <= (rectPtr->bbox[2] - halfWidth))
@@ -1239,7 +1238,7 @@ OvalToArea(
*/
halfWidth = width/2.0;
- if (ovalPtr->outline.gc == None) {
+ if (ovalPtr->outline.gc == NULL) {
halfWidth = 0.0;
}
oval[0] = ovalPtr->bbox[0] - halfWidth;
@@ -1256,8 +1255,8 @@ OvalToArea(
* return "outside".
*/
- if ((result == 0) && (ovalPtr->outline.gc != None)
- && (ovalPtr->fillGC == None)) {
+ if ((result == 0) && (ovalPtr->outline.gc != NULL)
+ && (ovalPtr->fillGC == NULL)) {
double centerX, centerY, height;
double xDelta1, yDelta1, xDelta2, yDelta2;
diff --git a/generic/tkScale.c b/generic/tkScale.c
index 8b016a2..216fd02 100644
--- a/generic/tkScale.c
+++ b/generic/tkScale.c
@@ -270,11 +270,11 @@ Tk_ScaleObjCmd(
scalePtr->activeBorder = NULL;
scalePtr->sliderRelief = TK_RELIEF_RAISED;
scalePtr->troughColorPtr = NULL;
- scalePtr->troughGC = None;
- scalePtr->copyGC = None;
+ scalePtr->troughGC = NULL;
+ scalePtr->copyGC = NULL;
scalePtr->tkfont = NULL;
scalePtr->textColorPtr = NULL;
- scalePtr->textGC = None;
+ scalePtr->textGC = NULL;
scalePtr->relief = TK_RELIEF_FLAT;
scalePtr->highlightWidth = 0;
scalePtr->highlightBorder = NULL;
@@ -291,7 +291,7 @@ Tk_ScaleObjCmd(
scalePtr->vertTroughX = 0;
scalePtr->vertLabelX = 0;
scalePtr->fontHeight = 0;
- scalePtr->cursor = None;
+ scalePtr->cursor = NULL;
scalePtr->takeFocusPtr = NULL;
scalePtr->flags = NEVER_SET;
@@ -518,13 +518,13 @@ DestroyScale(
NULL, TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
ScaleVarProc, scalePtr);
}
- if (scalePtr->troughGC != None) {
+ if (scalePtr->troughGC != NULL) {
Tk_FreeGC(scalePtr->display, scalePtr->troughGC);
}
- if (scalePtr->copyGC != None) {
+ if (scalePtr->copyGC != NULL) {
Tk_FreeGC(scalePtr->display, scalePtr->copyGC);
}
- if (scalePtr->textGC != None) {
+ if (scalePtr->textGC != NULL) {
Tk_FreeGC(scalePtr->display, scalePtr->textGC);
}
Tk_FreeConfigOptions((char *) scalePtr, scalePtr->optionTable,
@@ -611,7 +611,7 @@ ConfigureScale(
TCL_GLOBAL_ONLY);
if ((valuePtr != NULL) &&
(Tcl_GetDoubleFromObj(NULL, valuePtr, &value) == TCL_OK)) {
- scalePtr->value = TkRoundToResolution(scalePtr, value);
+ scalePtr->value = TkRoundValueToResolution(scalePtr, value);
}
}
@@ -620,10 +620,10 @@ ConfigureScale(
* orientation and creating GCs.
*/
- scalePtr->fromValue = TkRoundToResolution(scalePtr,
+ scalePtr->fromValue = TkRoundValueToResolution(scalePtr,
scalePtr->fromValue);
- scalePtr->toValue = TkRoundToResolution(scalePtr, scalePtr->toValue);
- scalePtr->tickInterval = TkRoundToResolution(scalePtr,
+ scalePtr->toValue = TkRoundValueToResolution(scalePtr, scalePtr->toValue);
+ scalePtr->tickInterval = TkRoundIntervalToResolution(scalePtr,
scalePtr->tickInterval);
/*
@@ -729,7 +729,7 @@ ScaleWorldChanged(
gcValues.foreground = scalePtr->troughColorPtr->pixel;
gc = Tk_GetGC(scalePtr->tkwin, GCForeground, &gcValues);
- if (scalePtr->troughGC != None) {
+ if (scalePtr->troughGC != NULL) {
Tk_FreeGC(scalePtr->display, scalePtr->troughGC);
}
scalePtr->troughGC = gc;
@@ -737,12 +737,12 @@ ScaleWorldChanged(
gcValues.font = Tk_FontId(scalePtr->tkfont);
gcValues.foreground = scalePtr->textColorPtr->pixel;
gc = Tk_GetGC(scalePtr->tkwin, GCForeground | GCFont, &gcValues);
- if (scalePtr->textGC != None) {
+ if (scalePtr->textGC != NULL) {
Tk_FreeGC(scalePtr->display, scalePtr->textGC);
}
scalePtr->textGC = gc;
- if (scalePtr->copyGC == None) {
+ if (scalePtr->copyGC == NULL) {
gcValues.graphics_exposures = False;
scalePtr->copyGC = Tk_GetGC(scalePtr->tkwin, GCGraphicsExposures,
&gcValues);
@@ -1119,10 +1119,14 @@ TkEventuallyRedrawScale(
/*
*--------------------------------------------------------------
*
- * TkRoundToResolution --
+ * TkRoundValueToResolution, TkRoundIntervalToResolution --
*
* Round a given floating-point value to the nearest multiple of the
* scale's resolution.
+ * TkRoundValueToResolution rounds an absolute value based on the from
+ * value as a reference.
+ * TkRoundIntervalToResolution rounds a relative value without
+ * reference, i.e. it rounds an interval.
*
* Results:
* The return value is the rounded result.
@@ -1134,7 +1138,16 @@ TkEventuallyRedrawScale(
*/
double
-TkRoundToResolution(
+TkRoundValueToResolution(
+ TkScale *scalePtr, /* Information about scale widget. */
+ double value) /* Value to round. */
+{
+ return TkRoundIntervalToResolution(scalePtr, value - scalePtr->fromValue)
+ + scalePtr->fromValue;
+}
+
+double
+TkRoundIntervalToResolution(
TkScale *scalePtr, /* Information about scale widget. */
double value) /* Value to round. */
{
@@ -1147,13 +1160,13 @@ TkRoundToResolution(
rounded = scalePtr->resolution * tick;
rem = value - rounded;
if (rem < 0) {
- if (rem <= -scalePtr->resolution/2) {
- rounded = (tick - 1.0) * scalePtr->resolution;
- }
+ if (rem <= -scalePtr->resolution/2) {
+ rounded = (tick - 1.0) * scalePtr->resolution;
+ }
} else {
- if (rem >= scalePtr->resolution/2) {
- rounded = (tick + 1.0) * scalePtr->resolution;
- }
+ if (rem >= scalePtr->resolution/2) {
+ rounded = (tick + 1.0) * scalePtr->resolution;
+ }
}
return rounded;
}
@@ -1238,7 +1251,7 @@ ScaleVarProc(
resultStr = "can't assign non-numeric value to scale variable";
ScaleSetVariable(scalePtr);
} else {
- scalePtr->value = TkRoundToResolution(scalePtr, value);
+ scalePtr->value = TkRoundValueToResolution(scalePtr, value);
/*
* This code is a bit tricky because it sets the scale's value before
@@ -1282,7 +1295,7 @@ TkScaleSetValue(
int invokeCommand) /* Non-zero means invoked -command option to
* notify of new value, 0 means don't. */
{
- value = TkRoundToResolution(scalePtr, value);
+ value = TkRoundValueToResolution(scalePtr, value);
if ((value < scalePtr->fromValue)
^ (scalePtr->toValue < scalePtr->fromValue)) {
value = scalePtr->fromValue;
@@ -1402,7 +1415,7 @@ TkScalePixelToValue(
}
value = scalePtr->fromValue +
value * (scalePtr->toValue - scalePtr->fromValue);
- return TkRoundToResolution(scalePtr, value);
+ return TkRoundValueToResolution(scalePtr, value);
}
/*
diff --git a/generic/tkScale.h b/generic/tkScale.h
index d0be190..296620d 100644
--- a/generic/tkScale.h
+++ b/generic/tkScale.h
@@ -151,7 +151,7 @@ typedef struct TkScale {
*/
int fontHeight; /* Height of scale font. */
- Tk_Cursor cursor; /* Current cursor for window, or None. */
+ Tk_Cursor cursor; /* Current cursor for window, or NULL. */
Tcl_Obj *takeFocusPtr; /* Value of -takefocus option; not used in the
* C code, but used by keyboard traversal
* scripts. May be NULL. */
@@ -219,7 +219,8 @@ typedef struct TkScale {
*/
MODULE_SCOPE void TkEventuallyRedrawScale(TkScale *scalePtr, int what);
-MODULE_SCOPE double TkRoundToResolution(TkScale *scalePtr, double value);
+MODULE_SCOPE double TkRoundValueToResolution(TkScale *scalePtr, double value);
+MODULE_SCOPE double TkRoundIntervalToResolution(TkScale *scalePtr, double value);
MODULE_SCOPE TkScale * TkpCreateScale(Tk_Window tkwin);
MODULE_SCOPE void TkpDestroyScale(TkScale *scalePtr);
MODULE_SCOPE void TkpDisplayScale(ClientData clientData);
diff --git a/generic/tkScrollbar.c b/generic/tkScrollbar.c
index 02fb740..030767b 100644
--- a/generic/tkScrollbar.c
+++ b/generic/tkScrollbar.c
@@ -187,7 +187,7 @@ Tk_ScrollbarObjCmd(
#endif /* TK_NO_DEPRECATED */
scrollPtr->firstFraction = 0.0;
scrollPtr->lastFraction = 0.0;
- scrollPtr->cursor = None;
+ scrollPtr->cursor = NULL;
scrollPtr->takeFocus = NULL;
scrollPtr->flags = 0;
diff --git a/generic/tkScrollbar.h b/generic/tkScrollbar.h
index 99f16a4..f7c39c8 100644
--- a/generic/tkScrollbar.h
+++ b/generic/tkScrollbar.h
@@ -123,7 +123,7 @@ typedef struct TkScrollbar {
* Miscellaneous information:
*/
- Tk_Cursor cursor; /* Current cursor for window, or None. */
+ Tk_Cursor cursor; /* Current cursor for window, or NULL. */
char *takeFocus; /* Value of -takefocus option; not used in the
* C code, but used by keyboard traversal
* scripts. Malloc'ed, but may be NULL. */
diff --git a/generic/tkSquare.c b/generic/tkSquare.c
index 2a64dbb..e40a684 100644
--- a/generic/tkSquare.c
+++ b/generic/tkSquare.c
@@ -169,7 +169,7 @@ SquareObjCmd(
squarePtr->widgetCmd = Tcl_CreateObjCommand(interp,
Tk_PathName(squarePtr->tkwin), SquareWidgetObjCmd, squarePtr,
SquareDeletedProc);
- squarePtr->gc = None;
+ squarePtr->gc = NULL;
squarePtr->optionTable = optionTable;
if (Tk_InitOptions(interp, squarePtr, optionTable, tkwin)
@@ -335,7 +335,7 @@ SquareConfigure(
Tk_SetWindowBackground(squarePtr->tkwin,
Tk_3DBorderColor(bgBorder)->pixel);
Tcl_GetBooleanFromObj(NULL, squarePtr->doubleBufferPtr, &doubleBuffer);
- if ((squarePtr->gc == None) && (doubleBuffer)) {
+ if ((squarePtr->gc == NULL) && doubleBuffer) {
XGCValues gcValues;
gcValues.function = GXcopy;
gcValues.graphics_exposures = False;
@@ -400,7 +400,7 @@ SquareObjEventProc(
if (squarePtr->tkwin != NULL) {
Tk_FreeConfigOptions((char *) squarePtr, squarePtr->optionTable,
squarePtr->tkwin);
- if (squarePtr->gc != None) {
+ if (squarePtr->gc != NULL) {
Tk_FreeGC(squarePtr->display, squarePtr->gc);
}
squarePtr->tkwin = NULL;
diff --git a/generic/tkText.c b/generic/tkText.c
index 280eec8..fc63992 100644
--- a/generic/tkText.c
+++ b/generic/tkText.c
@@ -406,7 +406,6 @@ static Tcl_Obj * TextGetText(const TkText *textPtr,
static void GenerateModifiedEvent(TkText *textPtr);
static void GenerateUndoStackEvent(TkText *textPtr);
static void UpdateDirtyFlag(TkSharedText *sharedPtr);
-static void RunAfterSyncCmd(ClientData clientData);
static void TextPushUndoAction(TkText *textPtr,
Tcl_Obj *undoString, int insert,
const TkTextIndex *index1Ptr,
@@ -587,7 +586,7 @@ CreateWidget(
textPtr->state = TK_TEXT_STATE_NORMAL;
textPtr->relief = TK_RELIEF_FLAT;
- textPtr->cursor = None;
+ textPtr->cursor = NULL;
textPtr->charWidth = 1;
textPtr->charHeight = 10;
textPtr->wrapMode = TEXT_WRAPMODE_CHAR;
@@ -1544,7 +1543,7 @@ TextWidgetObjCmd(
textPtr->afterSyncCmd = cmd;
} else {
textPtr->afterSyncCmd = cmd;
- Tcl_DoWhenIdle(RunAfterSyncCmd, (ClientData) textPtr);
+ Tcl_DoWhenIdle(TkTextRunAfterSyncCmd, (ClientData) textPtr);
}
break;
} else if (objc != 2) {
@@ -1556,7 +1555,7 @@ TextWidgetObjCmd(
Tcl_DecrRefCount(textPtr->afterSyncCmd);
}
textPtr->afterSyncCmd = NULL;
- TkTextUpdateLineMetrics(textPtr, 1,
+ TkTextUpdateLineMetrics(textPtr, 0,
TkBTreeNumLines(textPtr->sharedTextPtr->tree, textPtr), -1);
break;
}
@@ -2275,7 +2274,7 @@ ConfigureText(
textPtr->selTagPtr->affectsDisplay = 0;
textPtr->selTagPtr->affectsDisplayGeometry = 0;
if ((textPtr->selTagPtr->elideString != NULL)
- || (textPtr->selTagPtr->tkfont != None)
+ || (textPtr->selTagPtr->tkfont != NULL)
|| (textPtr->selTagPtr->justifyString != NULL)
|| (textPtr->selTagPtr->lMargin1String != NULL)
|| (textPtr->selTagPtr->lMargin2String != NULL)
@@ -5587,7 +5586,7 @@ UpdateDirtyFlag(
/*
*----------------------------------------------------------------------
*
- * RunAfterSyncCmd --
+ * TkTextRunAfterSyncCmd --
*
* This function is called by the event loop and executes the command
* scheduled by [.text sync -command $cmd].
@@ -5601,8 +5600,8 @@ UpdateDirtyFlag(
*----------------------------------------------------------------------
*/
-static void
-RunAfterSyncCmd(
+void
+TkTextRunAfterSyncCmd(
ClientData clientData) /* Information about text widget. */
{
register TkText *textPtr = clientData;
@@ -5623,7 +5622,7 @@ RunAfterSyncCmd(
code = Tcl_EvalObjEx(textPtr->interp, textPtr->afterSyncCmd, TCL_EVAL_GLOBAL);
if (code == TCL_ERROR) {
Tcl_AddErrorInfo(textPtr->interp, "\n (text sync)");
- Tcl_BackgroundError(textPtr->interp);
+ Tcl_BackgroundException(textPtr->interp, TCL_ERROR);
}
Tcl_Release((ClientData) textPtr->interp);
Tcl_DecrRefCount(textPtr->afterSyncCmd);
diff --git a/generic/tkText.h b/generic/tkText.h
index 5e84fd5..8fb4134 100644
--- a/generic/tkText.h
+++ b/generic/tkText.h
@@ -677,7 +677,7 @@ typedef struct TkText {
/* Color for drawing traversal highlight area
* when highlight is off. */
XColor *highlightColorPtr; /* Color for drawing traversal highlight. */
- Tk_Cursor cursor; /* Current cursor for window, or None. */
+ Tk_Cursor cursor; /* Current cursor for window, or NULL. */
XColor *fgColor; /* Default foreground color for text. */
Tk_Font tkfont; /* Default font for displaying text. */
int charWidth; /* Width of average character in default
@@ -1080,7 +1080,7 @@ MODULE_SCOPE int TkTextGetObjIndex(Tcl_Interp *interp, TkText *textPtr,
MODULE_SCOPE int TkTextSharedGetObjIndex(Tcl_Interp *interp,
TkSharedText *sharedTextPtr, Tcl_Obj *idxPtr,
TkTextIndex *indexPtr);
-MODULE_SCOPE const TkTextIndex *TkTextGetIndexFromObj(Tcl_Interp *interp,
+MODULE_SCOPE const TkTextIndex *TkTextGetIndexFromObj(Tcl_Interp *interp,
TkText *textPtr, Tcl_Obj *objPtr);
MODULE_SCOPE TkTextTabArray *TkTextGetTabs(Tcl_Interp *interp,
TkText *textPtr, Tcl_Obj *stringPtr);
@@ -1169,7 +1169,7 @@ MODULE_SCOPE int TkTextYviewCmd(TkText *textPtr, Tcl_Interp *interp,
int objc, Tcl_Obj *const objv[]);
MODULE_SCOPE void TkTextWinFreeClient(Tcl_HashEntry *hPtr,
TkTextEmbWindowClient *client);
-
+MODULE_SCOPE void TkTextRunAfterSyncCmd(ClientData clientData);
#endif /* _TKTEXT */
/*
diff --git a/generic/tkTextDisp.c b/generic/tkTextDisp.c
index 0ad9ead..66ff744 100644
--- a/generic/tkTextDisp.c
+++ b/generic/tkTextDisp.c
@@ -491,13 +491,15 @@ static TkTextDispChunk *baseCharChunkPtr = NULL;
* different character might be under the mouse
* cursor now). Need to recompute the current
* character before the next redisplay.
+ * OUT_OF_SYNC 1 means that the last <<WidgetViewSync>> event had
+ * value 0, indicating that the widget is out of sync.
*/
#define DINFO_OUT_OF_DATE 1
#define REDRAW_PENDING 2
#define REDRAW_BORDERS 4
#define REPICK_NEEDED 8
-
+#define OUT_OF_SYNC 16
/*
* Action values for FreeDLines:
*
@@ -658,7 +660,7 @@ TkTextCreateDInfo(
dInfoPtr = ckalloc(sizeof(TextDInfo));
Tcl_InitHashTable(&dInfoPtr->styleTable, sizeof(StyleValues)/sizeof(int));
dInfoPtr->dLinePtr = NULL;
- dInfoPtr->copyGC = None;
+ dInfoPtr->copyGC = NULL;
gcValues.graphics_exposures = True;
dInfoPtr->scrollGC = Tk_GetGC(textPtr->tkwin, GCGraphicsExposures,
&gcValues);
@@ -675,7 +677,7 @@ TkTextCreateDInfo(
dInfoPtr->scanTotalYScroll = 0;
dInfoPtr->scanMarkY = 0;
dInfoPtr->dLinesInvalidated = 0;
- dInfoPtr->flags = DINFO_OUT_OF_DATE;
+ dInfoPtr->flags = 0;
dInfoPtr->topPixelOffset = 0;
dInfoPtr->newTopPixelOffset = 0;
dInfoPtr->currentMetricUpdateLine = -1;
@@ -722,7 +724,7 @@ TkTextFreeDInfo(
FreeDLines(textPtr, dInfoPtr->dLinePtr, NULL, DLINE_UNLINK);
Tcl_DeleteHashTable(&dInfoPtr->styleTable);
- if (dInfoPtr->copyGC != None) {
+ if (dInfoPtr->copyGC != NULL) {
Tk_FreeGC(textPtr->display, dInfoPtr->copyGC);
}
Tk_FreeGC(textPtr->display, dInfoPtr->scrollGC);
@@ -854,7 +856,7 @@ GetStyle(
border = tagPtr->selBorder;
}
- if ((tagPtr->selFgColor != None) && (isSelected)) {
+ if ((tagPtr->selFgColor != NULL) && isSelected) {
fgColor = tagPtr->selFgColor;
}
@@ -881,11 +883,11 @@ GetStyle(
styleValues.bgStipple = tagPtr->bgStipple;
bgStipplePrio = tagPtr->priority;
}
- if ((fgColor != None) && (tagPtr->priority > fgPrio)) {
+ if ((fgColor != NULL) && (tagPtr->priority > fgPrio)) {
styleValues.fgColor = fgColor;
fgPrio = tagPtr->priority;
}
- if ((tagPtr->tkfont != None) && (tagPtr->priority > fontPrio)) {
+ if ((tagPtr->tkfont != NULL) && (tagPtr->priority > fontPrio)) {
styleValues.tkfont = tagPtr->tkfont;
fontPrio = tagPtr->priority;
}
@@ -923,9 +925,9 @@ GetStyle(
&& (tagPtr->priority > overstrikePrio)) {
styleValues.overstrike = tagPtr->overstrike;
overstrikePrio = tagPtr->priority;
- if (tagPtr->overstrikeColor != None) {
+ if (tagPtr->overstrikeColor != NULL) {
styleValues.overstrikeColor = tagPtr->overstrikeColor;
- } else if (fgColor != None) {
+ } else if (fgColor != NULL) {
styleValues.overstrikeColor = fgColor;
}
}
@@ -968,9 +970,9 @@ GetStyle(
&& (tagPtr->priority > underlinePrio)) {
styleValues.underline = tagPtr->underline;
underlinePrio = tagPtr->priority;
- if (tagPtr->underlineColor != None) {
+ if (tagPtr->underlineColor != NULL) {
styleValues.underlineColor = tagPtr->underlineColor;
- } else if (fgColor != None) {
+ } else if (fgColor != NULL) {
styleValues.underlineColor = fgColor;
}
}
@@ -1017,7 +1019,7 @@ GetStyle(
}
stylePtr->bgGC = Tk_GetGC(textPtr->tkwin, mask, &gcValues);
} else {
- stylePtr->bgGC = None;
+ stylePtr->bgGC = NULL;
}
mask = GCFont;
gcValues.font = Tk_FontId(styleValues.tkfont);
@@ -1067,16 +1069,16 @@ FreeStyle(
/* Information about style to free. */
{
if (stylePtr->refCount-- <= 1) {
- if (stylePtr->bgGC != None) {
+ if (stylePtr->bgGC != NULL) {
Tk_FreeGC(textPtr->display, stylePtr->bgGC);
}
- if (stylePtr->fgGC != None) {
+ if (stylePtr->fgGC != NULL) {
Tk_FreeGC(textPtr->display, stylePtr->fgGC);
}
- if (stylePtr->ulGC != None) {
+ if (stylePtr->ulGC != NULL) {
Tk_FreeGC(textPtr->display, stylePtr->ulGC);
}
- if (stylePtr->ovGC != None) {
+ if (stylePtr->ovGC != NULL) {
Tk_FreeGC(textPtr->display, stylePtr->ovGC);
}
Tcl_DeleteHashEntry(stylePtr->hPtr);
@@ -2681,7 +2683,7 @@ DisplayLineBackground(
if ((chunkPtr->nextPtr == NULL) && (rightX < maxX)) {
rightX = maxX;
}
- if (chunkPtr->stylePtr->bgGC != None) {
+ if (chunkPtr->stylePtr->bgGC != NULL) {
/*
* Not visible - bail out now.
*/
@@ -3063,16 +3065,19 @@ AsyncUpdateLineMetrics(
* We have looped over all lines, so we're done. We must release our
* refCount on the widget (the timer token was already set to NULL
* above). If there is a registered aftersync command, run that first.
+ * Cancel any pending idle task which would try to run the command
+ * after the afterSyncCmd pointer had been set to NULL.
*/
if (textPtr->afterSyncCmd) {
int code;
+ Tcl_CancelIdleCall(TkTextRunAfterSyncCmd, textPtr);
Tcl_Preserve((ClientData) textPtr->interp);
code = Tcl_EvalObjEx(textPtr->interp, textPtr->afterSyncCmd,
TCL_EVAL_GLOBAL);
if (code == TCL_ERROR) {
Tcl_AddErrorInfo(textPtr->interp, "\n (text sync)");
- Tcl_BackgroundError(textPtr->interp);
+ Tcl_BackgroundException(textPtr->interp, TCL_ERROR);
}
Tcl_Release((ClientData) textPtr->interp);
Tcl_DecrRefCount(textPtr->afterSyncCmd);
@@ -3084,7 +3089,6 @@ AsyncUpdateLineMetrics(
* with its internal data (actually it will be after the next trip
* through the event loop, because the widget redraws at idle-time).
*/
-
GenerateWidgetViewSyncEvent(textPtr, 1);
if (textPtr->refCount-- <= 1) {
@@ -3108,8 +3112,14 @@ AsyncUpdateLineMetrics(
* GenerateWidgetViewSyncEvent --
*
* Send the <<WidgetViewSync>> event related to the text widget
- * line metrics asynchronous update.
- * This is equivalent to:
+ * line metrics asynchronous update. These events should only
+ * be sent when the sync status has changed. So this function
+ * compares the requested state with the state saved in the
+ * TkText structure, and only generates the event if they are
+ * different. This means that it is safe to call this function
+ * at any time when the state is known.
+ *
+ * If an event is sent, the effect is equivalent to:
* event generate $textWidget <<WidgetViewSync>> -data $s
* where $s is the sync status: true (when the widget view is in
* sync with its internal data) or false (when it is not).
@@ -3125,9 +3135,12 @@ AsyncUpdateLineMetrics(
static void
GenerateWidgetViewSyncEvent(
- TkText *textPtr, /* Information about text widget. */
- Bool InSync) /* true if in sync, false otherwise */
+ TkText *textPtr, /* Information about text widget. */
+ Bool InSync) /* true if becoming in sync, false otherwise */
{
+ Bool NewSyncState = (InSync != 0); /* ensure 0 or 1 value */
+ Bool OldSyncState = !(textPtr->dInfoPtr->flags & OUT_OF_SYNC);
+
/*
* OSX 10.14 needs to be told to display the window when the Text Widget
* is in sync. (That is, to run DisplayText inside of the drawRect
@@ -3140,8 +3153,15 @@ GenerateWidgetViewSyncEvent(
FORCE_DISPLAY(textPtr->tkwin);
}
- TkSendVirtualEvent(textPtr->tkwin, "WidgetViewSync",
- Tcl_NewBooleanObj(InSync));
+ if (NewSyncState != OldSyncState) {
+ if (NewSyncState) {
+ textPtr->dInfoPtr->flags &= ~OUT_OF_SYNC;
+ } else {
+ textPtr->dInfoPtr->flags |= OUT_OF_SYNC;
+ }
+ TkSendVirtualEvent(textPtr->tkwin, "WidgetViewSync",
+ Tcl_NewBooleanObj(NewSyncState));
+ }
}
/*
@@ -3184,6 +3204,9 @@ TkTextUpdateLineMetrics(
TkTextLine *linePtr = NULL;
int count = 0;
int totalLines = TkBTreeNumLines(textPtr->sharedTextPtr->tree, textPtr);
+ int fullUpdateRequested = (lineNum == 0 &&
+ endLine == totalLines &&
+ doThisMuch == -1);
if (totalLines == 0) {
/*
@@ -3194,6 +3217,7 @@ TkTextUpdateLineMetrics(
}
while (1) {
+
/*
* Get a suitable line.
*/
@@ -3220,6 +3244,8 @@ TkTextUpdateLineMetrics(
*/
if (textPtr->dInfoPtr->metricEpoch == TCL_AUTO_LENGTH && lineNum == endLine) {
+
+
/*
* We have looped over all lines, so we're done.
*/
@@ -3243,10 +3269,12 @@ TkTextUpdateLineMetrics(
if (TkBTreeLinePixelEpoch(textPtr, linePtr)
== textPtr->dInfoPtr->lineMetricUpdateEpoch) {
+
/*
* This line is already up to date. That means there's nothing
* to do here.
*/
+
} else if (doThisMuch == -1) {
count += 8 * TkTextUpdateOneLine(textPtr, linePtr, 0,NULL,0);
} else {
@@ -3268,6 +3296,7 @@ TkTextUpdateLineMetrics(
indexPtr = &textPtr->dInfoPtr->metricIndex;
pixelHeight = textPtr->dInfoPtr->metricPixelHeight;
} else {
+
/*
* We must reset the partial line height calculation data
* here, so we don't use it when it is out of date.
@@ -3291,6 +3320,7 @@ TkTextUpdateLineMetrics(
pixelHeight, indexPtr, 1);
if (indexPtr->linePtr == linePtr) {
+
/*
* We didn't complete the logical line, because it
* produced very many display lines, which must be because
@@ -3299,6 +3329,7 @@ TkTextUpdateLineMetrics(
*/
if (pixelHeight == 0) {
+
/*
* These have already been stored, unless we just
* started the new line.
@@ -3320,6 +3351,7 @@ TkTextUpdateLineMetrics(
textPtr->dInfoPtr->metricEpoch = -1;
}
} else {
+
/*
* We must never recalculate the height of the last artificial
* line. It must stay at zero, and if we recalculate it, it will
@@ -3344,13 +3376,17 @@ TkTextUpdateLineMetrics(
}
}
if (doThisMuch == -1) {
+
/*
- * If we were requested to provide a full update, then also update the
- * scrollbar.
+ * If we were requested to update the entire range, then also update
+ * the scrollbar.
*/
GetYView(textPtr->interp, textPtr, 1);
}
+ if (fullUpdateRequested) {
+ GenerateWidgetViewSyncEvent(textPtr, 1);
+ }
return lineNum;
}
@@ -3519,8 +3555,12 @@ TextInvalidateLineMetrics(
textPtr->refCount++;
dInfoPtr->lineUpdateTimer = Tcl_CreateTimerHandler(1,
AsyncUpdateLineMetrics, textPtr);
- GenerateWidgetViewSyncEvent(textPtr, 0);
}
+
+ /*
+ * The widget is out of sync: send a <<WidgetViewSync>> event.
+ */
+ GenerateWidgetViewSyncEvent(textPtr, 0);
}
/*
@@ -4537,7 +4577,7 @@ DisplayText(
dlPtr->spaceAbove,
dlPtr->height-dlPtr->spaceAbove-dlPtr->spaceBelow,
dlPtr->baseline - dlPtr->spaceAbove, NULL,
- (Drawable) None, dlPtr->y + dlPtr->spaceAbove);
+ None, dlPtr->y + dlPtr->spaceAbove);
}
}
}
@@ -5173,7 +5213,7 @@ TkTextRelayoutWindow(
gcValues.graphics_exposures = False;
newGC = Tk_GetGC(textPtr->tkwin, GCGraphicsExposures, &gcValues);
- if (dInfoPtr->copyGC != None) {
+ if (dInfoPtr->copyGC != NULL) {
Tk_FreeGC(textPtr->display, dInfoPtr->copyGC);
}
dInfoPtr->copyGC = newGC;
@@ -5262,9 +5302,7 @@ TkTextRelayoutWindow(
inSync = 0;
}
- if (!inSync) {
- GenerateWidgetViewSyncEvent(textPtr, 0);
- }
+ GenerateWidgetViewSyncEvent(textPtr, inSync);
}
}
@@ -6289,11 +6327,7 @@ TkTextPendingsync(
{
TextDInfo *dInfoPtr = textPtr->dInfoPtr;
- return (
- (!(dInfoPtr->flags & REDRAW_PENDING) &&
- (dInfoPtr->metricEpoch == TCL_AUTO_LENGTH) &&
- (dInfoPtr->lastMetricUpdateLine == dInfoPtr->currentMetricUpdateLine)) ?
- 0 : 1);
+ return ((dInfoPtr->flags & OUT_OF_SYNC) != 0);
}
/*
@@ -7987,7 +8021,7 @@ CharDisplayProc(
*/
if (!sValuePtr->elide && (numBytes > offsetBytes)
- && (stylePtr->fgGC != None)) {
+ && (stylePtr->fgGC != NULL)) {
#if TK_DRAW_IN_CONTEXT
int start = ciPtr->baseOffset + offsetBytes;
int len = ciPtr->numBytes - offsetBytes;
diff --git a/generic/tkTextTag.c b/generic/tkTextTag.c
index 0a749c4..e20bf58 100644
--- a/generic/tkTextTag.c
+++ b/generic/tkTextTag.c
@@ -516,7 +516,7 @@ TkTextTagCmd(
tagPtr->affectsDisplay = 0;
tagPtr->affectsDisplayGeometry = 0;
if ((tagPtr->elideString != NULL)
- || (tagPtr->tkfont != None)
+ || (tagPtr->tkfont != NULL)
|| (tagPtr->justifyString != NULL)
|| (tagPtr->lMargin1String != NULL)
|| (tagPtr->lMargin2String != NULL)
diff --git a/generic/tkWindow.c b/generic/tkWindow.c
index 23c0891..3d91927 100644
--- a/generic/tkWindow.c
+++ b/generic/tkWindow.c
@@ -2089,7 +2089,7 @@ void
Tk_UndefineCursor(
Tk_Window tkwin) /* Window to manipulate. */
{
- Tk_DefineCursor(tkwin, None);
+ Tk_DefineCursor(tkwin, NULL);
}
void
diff --git a/generic/ttk/ttkClassicTheme.c b/generic/ttk/ttkClassicTheme.c
index 117d928..48e856e 100644
--- a/generic/ttk/ttkClassicTheme.c
+++ b/generic/ttk/ttkClassicTheme.c
@@ -6,8 +6,6 @@
*/
#include "tkInt.h"
-#include <X11/Xlib.h>
-#include <X11/Xutil.h>
#include "ttkTheme.h"
#define DEFAULT_BORDERWIDTH "2"
diff --git a/generic/ttk/ttkDefaultTheme.c b/generic/ttk/ttkDefaultTheme.c
index 6d0b29b..e4bfeca 100644
--- a/generic/ttk/ttkDefaultTheme.c
+++ b/generic/ttk/ttkDefaultTheme.c
@@ -5,8 +5,6 @@
*/
#include "tkInt.h"
-#include <X11/Xlib.h>
-#include <X11/Xutil.h>
#include "ttkTheme.h"
#if defined(_WIN32)
diff --git a/generic/ttk/ttkEntry.c b/generic/ttk/ttkEntry.c
index 32491dd..49b6553 100644
--- a/generic/ttk/ttkEntry.c
+++ b/generic/ttk/ttkEntry.c
@@ -9,8 +9,6 @@
*/
#include "tkInt.h"
-#include <X11/Xatom.h>
-
#include "ttkTheme.h"
#include "ttkWidget.h"
@@ -357,7 +355,7 @@ EntryFetchSelection(
ClientData clientData, int offset, char *buffer, int maxBytes)
{
Entry *entryPtr = clientData;
- size_t byteCount;
+ int byteCount;
const char *string;
const char *selStart, *selEnd;
@@ -371,7 +369,7 @@ EntryFetchSelection(
selEnd = Tcl_UtfAtIndex(selStart,
entryPtr->entry.selectLast - entryPtr->entry.selectFirst);
byteCount = selEnd - selStart - offset;
- if (byteCount > (size_t)maxBytes) {
+ if (byteCount > maxBytes) {
/* @@@POSSIBLE BUG: Can transfer partial UTF-8 sequences. Is this OK? */
byteCount = maxBytes;
}
@@ -1179,7 +1177,7 @@ static GC EntryGetGC(Entry *entryPtr, Tcl_Obj *colorObj, TkRegion clip)
mask |= GCForeground;
}
gc = Tk_GetGC(entryPtr->core.tkwin, mask, &gcValues);
- if (clip != None) {
+ if (clip != NULL) {
TkSetRegion(Tk_Display(entryPtr->core.tkwin), gc, clip);
}
return gc;
@@ -1290,7 +1288,7 @@ static void EntryDisplay(void *clientData, Drawable d)
cursorX = field.x + field.width - cursorWidth;
}
- gc = EntryGetGC(entryPtr, es.insertColorObj, None);
+ gc = EntryGetGC(entryPtr, es.insertColorObj, NULL);
XFillRectangle(Tk_Display(tkwin), d, gc,
cursorX, cursorY, cursorWidth, cursorHeight);
Tk_FreeGC(Tk_Display(tkwin), gc);
@@ -1336,7 +1334,7 @@ static void EntryDisplay(void *clientData, Drawable d)
* it from the Xft guts (if they're being used).
*/
#ifdef HAVE_XFT
- TkUnixSetXftClipRegion(None);
+ TkUnixSetXftClipRegion(NULL);
#endif
TkDestroyRegion(clipRegion);
}
diff --git a/generic/ttk/ttkLabel.c b/generic/ttk/ttkLabel.c
index 91be033..d7a1f93 100644
--- a/generic/ttk/ttkLabel.c
+++ b/generic/ttk/ttkLabel.c
@@ -182,7 +182,7 @@ static void TextDraw(TextElement *text, Tk_Window tkwin, Drawable d, Ttk_Box b)
if (clipRegion != NULL) {
#ifdef HAVE_XFT
- TkUnixSetXftClipRegion(None);
+ TkUnixSetXftClipRegion(NULL);
#endif
XSetClipMask(Tk_Display(tkwin), gc1, None);
XSetClipMask(Tk_Display(tkwin), gc2, None);
diff --git a/generic/ttk/ttkState.c b/generic/ttk/ttkState.c
index 7ac6740..9e5cf4b 100644
--- a/generic/ttk/ttkState.c
+++ b/generic/ttk/ttkState.c
@@ -129,7 +129,7 @@ static void StateSpecUpdateString(Tcl_Obj *objPtr)
unsigned int mask = onbits | offbits;
Tcl_DString result;
int i;
- size_t len;
+ int len;
Tcl_DStringInit(&result);
@@ -145,14 +145,14 @@ static void StateSpecUpdateString(Tcl_Obj *objPtr)
len = Tcl_DStringLength(&result);
if (len) {
/* 'len' includes extra trailing ' ' */
- objPtr->bytes = Tcl_Alloc(len);
+ objPtr->bytes = ckalloc(len);
objPtr->length = len-1;
strncpy(objPtr->bytes, Tcl_DStringValue(&result), len-1);
objPtr->bytes[len-1] = '\0';
} else {
/* empty string */
objPtr->length = 0;
- objPtr->bytes = Tcl_Alloc(1);
+ objPtr->bytes = ckalloc(1);
*objPtr->bytes = '\0';
}
diff --git a/library/bgerror.tcl b/library/bgerror.tcl
index b15387e..574ad8b 100644
--- a/library/bgerror.tcl
+++ b/library/bgerror.tcl
@@ -97,7 +97,7 @@ proc ::tk::dialog::error::ReturnInDetails w {
# Arguments:
# err - The error message.
#
-proc ::tk::dialog::error::bgerror err {
+proc ::tk::dialog::error::bgerror {err {flag 1}} {
global errorInfo
variable button
@@ -106,15 +106,20 @@ proc ::tk::dialog::error::bgerror err {
set ret [catch {::tkerror $err} msg];
if {$ret != 1} {return -code $ret $msg}
- # Ok the application's tkerror either failed or was not found
- # we use the default dialog then :
+ # The application's tkerror either failed or was not found
+ # so we use the default dialog. But on Aqua we cannot display
+ # the dialog if the background error occurs in an idle task
+ # being processed inside of [NSView drawRect]. In that case
+ # we post the dialog as an after task instead.
set windowingsystem [tk windowingsystem]
if {$windowingsystem eq "aqua"} {
- set ok [mc Ok]
- } else {
- set ok [mc OK]
+ if $flag {
+ after 500 [list bgerror "$err" 0]
+ return
+ }
}
+ set ok [mc OK]
# Truncate the message if it is too wide (>maxLine characters) or
# too tall (>4 lines). Truncation occurs at the first point at
# which one of those conditions is met.
diff --git a/library/demos/dialog1.tcl b/library/demos/dialog1.tcl
index 5c572be..976e955 100644
--- a/library/demos/dialog1.tcl
+++ b/library/demos/dialog1.tcl
@@ -2,8 +2,16 @@
#
# This demonstration script creates a dialog box with a local grab.
+interp create slave
+load {} Tk slave
+slave eval {
+ wm title . slave
+ wm geometry . +700+30
+ pack [text .t -width 30 -height 10]
+}
+
after idle {.dialog1.msg configure -wraplength 4i}
-set i [tk_dialog .dialog1 "Dialog with local grab" {This is a modal dialog box. It uses Tk's "grab" command to create a "local grab" on the dialog box. The grab prevents any pointer-related events from getting to any other windows in the application until you have answered the dialog by invoking one of the buttons below. However, you can still interact with other applications.} \
+set i [tk_dialog .dialog1 "Dialog with local grab" {This is a modal dialog box. It uses Tk's "grab" command to create a "local grab" on the dialog box. The grab prevents any mouse or keyboard events from getting to any other windows in the application until you have answered the dialog by invoking one of the buttons below. However, you can still interact with other applications. For example, you should be able to edit text in the window named "slave" which was created by a slave interpreter.} \
info 0 OK Cancel {Show Code}]
switch $i {
@@ -11,3 +19,7 @@ switch $i {
1 {puts "You pressed Cancel"}
2 {showCode .dialog1}
}
+
+if {[interp exists slave]} {
+ interp delete slave
+}
diff --git a/library/demos/dialog2.tcl b/library/demos/dialog2.tcl
index 2f45da8..6ae27a8 100644
--- a/library/demos/dialog2.tcl
+++ b/library/demos/dialog2.tcl
@@ -8,7 +8,8 @@ after idle {
after 100 {
grab -global .dialog2
}
-set i [tk_dialog .dialog2 "Dialog with global grab" {This dialog box uses a global grab, so it prevents you from interacting with anything on your display until you invoke one of the buttons below. Global grabs are almost always a bad idea; don't use them unless you're truly desperate.} warning 0 OK Cancel {Show Code}]
+set i [tk_dialog .dialog2 "Dialog with global grab" {This dialog box uses a global grab. If you are using an X11 window manager you will be prevented from interacting with anything on your display until you invoke one of the buttons below. This is almost always a bad idea; don't use global grabs with X11 unless you're truly desperate. On macOS systems you will not be able to interact with any window belonging to this process, but interaction with other macOS Applications will still be possible.}\
+warning 0 OK Cancel {Show Code}]
switch $i {
0 {puts "You pressed OK"}
diff --git a/library/demos/puzzle.tcl b/library/demos/puzzle.tcl
index 4f7f955..eebe87a 100644
--- a/library/demos/puzzle.tcl
+++ b/library/demos/puzzle.tcl
@@ -73,7 +73,7 @@ for {set i 0} {$i < 15} {set i [expr {$i+1}]} {
set num [lindex $order $i]
set xpos($num) [expr {($i%4)*.25}]
set ypos($num) [expr {($i/4)*.25}]
- button $w.frame.$num -relief raised -text $num -highlightthickness 0 \
+ button $w.frame.$num -relief raised -text $num -bd 0 -highlightthickness 0 \
-command "puzzleSwitch $w $num"
place $w.frame.$num -relx $xpos($num) -rely $ypos($num) \
-relwidth .25 -relheight .25
diff --git a/library/menu.tcl b/library/menu.tcl
index ba66b92..8d06868 100644
--- a/library/menu.tcl
+++ b/library/menu.tcl
@@ -234,6 +234,7 @@ proc ::tk::MbLeave w {
}
}
+
# ::tk::MbPost --
# Given a menubutton, this procedure does all the work of posting
# its associated menu and unposting any other menu that is currently
@@ -282,101 +283,17 @@ proc ::tk::MbPost {w {x {}} {y {}}} {
set Priv(focus) [focus]
$menu activate none
GenerateMenuSelect $menu
-
- # If this looks like an option menubutton then post the menu so
- # that the current entry is on top of the mouse. Otherwise post
- # the menu just below the menubutton, as for a pull-down.
-
update idletasks
- if {[catch {
- switch [$w cget -direction] {
- above {
- set x [winfo rootx $w]
- set y [expr {[winfo rooty $w] - [winfo reqheight $menu]}]
- # if we go offscreen to the top, show as 'below'
- if {$y < [winfo vrooty $w]} {
- set y [expr {[winfo vrooty $w] + [winfo rooty $w] + [winfo reqheight $w]}]
- }
- PostOverPoint $menu $x $y
- }
- below {
- set x [winfo rootx $w]
- set y [expr {[winfo rooty $w] + [winfo height $w]}]
- # if we go offscreen to the bottom, show as 'above'
- set mh [winfo reqheight $menu]
- if {($y + $mh) > ([winfo vrooty $w] + [winfo vrootheight $w])} {
- set y [expr {[winfo vrooty $w] + [winfo vrootheight $w] + [winfo rooty $w] - $mh}]
- }
- PostOverPoint $menu $x $y
- }
- left {
- set x [expr {[winfo rootx $w] - [winfo reqwidth $menu]}]
- set y [expr {(2 * [winfo rooty $w] + [winfo height $w]) / 2}]
- set entry [MenuFindName $menu [$w cget -text]]
- if {$entry eq ""} {
- set entry 0
- }
- if {[$w cget -indicatoron]} {
- if {$entry == [$menu index last]} {
- incr y [expr {-([$menu yposition $entry] \
- + [winfo reqheight $menu])/2}]
- } else {
- incr y [expr {-([$menu yposition $entry] \
- + [$menu yposition [expr {$entry+1}]])/2}]
- }
- }
- PostOverPoint $menu $x $y
- if {$entry ne "" \
- && [$menu entrycget $entry -state] ne "disabled"} {
- $menu activate $entry
- GenerateMenuSelect $menu
- }
- }
- right {
- set x [expr {[winfo rootx $w] + [winfo width $w]}]
- set y [expr {(2 * [winfo rooty $w] + [winfo height $w]) / 2}]
- set entry [MenuFindName $menu [$w cget -text]]
- if {$entry eq ""} {
- set entry 0
- }
- if {[$w cget -indicatoron]} {
- if {$entry == [$menu index last]} {
- incr y [expr {-([$menu yposition $entry] \
- + [winfo reqheight $menu])/2}]
- } else {
- incr y [expr {-([$menu yposition $entry] \
- + [$menu yposition [expr {$entry+1}]])/2}]
- }
- }
- PostOverPoint $menu $x $y
- if {$entry ne "" \
- && [$menu entrycget $entry -state] ne "disabled"} {
- $menu activate $entry
- GenerateMenuSelect $menu
- }
- }
- default {
- if {[$w cget -indicatoron]} {
- if {$y eq ""} {
- set x [expr {[winfo rootx $w] + [winfo width $w]/2}]
- set y [expr {[winfo rooty $w] + [winfo height $w]/2}]
- }
- PostOverPoint $menu $x $y [MenuFindName $menu [$w cget -text]]
- } else {
- PostOverPoint $menu [winfo rootx $w] [expr {[winfo rooty $w]+[winfo height $w]}]
- }
- }
- }
- } msg opt]} {
+
+ if {[catch {PostMenubuttonMenu $w $menu} msg opt]} {
# Error posting menu (e.g. bogus -postcommand). Unpost it and
# reflect the error.
-
MenuUnpost {}
return -options $opt $msg
}
set Priv(tearoff) $tearoff
- if {$tearoff != 0} {
+ if {$tearoff != 0 && [tk windowingsystem] ne "aqua"} {
focus $menu
if {[winfo viewable $w]} {
SaveGrabInfo $w
@@ -576,11 +493,13 @@ proc ::tk::MenuMotion {menu x y state} {
if {[string is false $mode]} {
set delay [expr {[$menu cget -type] eq "menubar" ? 0 : 50}]
if {[$menu type $index] eq "cascade"} {
+ # Catch these postcascade commands since the menu could be
+ # destroyed before they run.
set Priv(menuActivatedTimer) \
- [after $delay [list $menu postcascade active]]
+ [after $delay "catch {$menu postcascade active}"]
} else {
set Priv(menuDeactivatedTimer) \
- [after $delay [list $menu postcascade none]]
+ [after $delay "catch {$menu postcascade none}"]
}
}
}
@@ -1208,10 +1127,118 @@ proc ::tk::MenuFindName {menu s} {
return ""
}
+# ::tk::PostMenubuttonMenu --
+#
+# Given a menubutton and a menu, this procedure posts the menu at the
+# appropriate location. If the menubutton looks like an option
+# menubutton, meaning that the indicator is on and the direction is
+# neither above nor below, then the menu is posted so that the current
+# entry is vertically aligned with the menubutton. On the Mac this
+# will expose a small amount of the blue indicator on the right hand
+# side. On other platforms the entry is centered over the button.
+
+if {[tk windowingsystem] eq "aqua"} {
+ proc ::tk::PostMenubuttonMenu {button menu} {
+ set entry ""
+ if {[$button cget -indicatoron]} {
+ set entry [MenuFindName $menu [$button cget -text]]
+ if {$entry eq ""} {
+ set entry 0
+ }
+ }
+ set x [winfo rootx $button]
+ set y [expr {2 + [winfo rooty $button]}]
+ switch [$button cget -direction] {
+ above {
+ set entry ""
+ incr y [expr {4 - [winfo reqheight $menu]}]
+ }
+ below {
+ set entry ""
+ incr y [expr {2 + [winfo height $button]}]
+ }
+ left {
+ incr x [expr {-[winfo reqwidth $menu]}]
+ }
+ right {
+ incr x [winfo width $button]
+ }
+ default {
+ incr x [expr {[winfo width $button] - [winfo reqwidth $menu] - 5}]
+ }
+ }
+ PostOverPoint $menu $x $y $entry
+ }
+} else {
+ proc ::tk::PostMenubuttonMenu {button menu} {
+ set entry ""
+ if {[$button cget -indicatoron]} {
+ set entry [MenuFindName $menu [$button cget -text]]
+ if {$entry eq ""} {
+ set entry 0
+ }
+ }
+ if {$entry ne ""} {
+ if {$entry == [$menu index last]} {
+ set entryHeight [expr {[winfo reqheight $menu] \
+ - [$menu yposition $entry]}]
+ } else {
+ set entryHeight [expr {[$menu yposition [expr {$entry+1}]] \
+ - [$menu yposition $entry]}]
+ }
+ }
+ set x [winfo rootx $button]
+ set y [winfo rooty $button]
+ switch [$button cget -direction] {
+ above {
+ incr y [expr {-[winfo reqheight $menu]}]
+ # if we go offscreen to the top, show as 'below'
+ if {$y < [winfo vrooty $button]} {
+ set y [expr {[winfo vrooty $button] + [winfo rooty $button]\
+ + [winfo reqheight $button]}]
+ }
+ set entry {}
+ }
+ below {
+ incr y [winfo height $button]
+ # if we go offscreen to the bottom, show as 'above'
+ set mh [winfo reqheight $menu]
+ if {($y + $mh) > ([winfo vrooty $button] + [winfo vrootheight $button])} {
+ set y [expr {[winfo vrooty $button] + [winfo vrootheight $button] \
+ + [winfo rooty $button] - $mh}]
+ }
+ set entry {}
+ }
+ left {
+ # It is not clear why this is needed.
+ if {[tk windowingsystem] eq "win32"} {
+ incr x [expr {-4 - [winfo reqwidth $button] / 2}]
+ }
+ incr x [expr {- [winfo reqwidth $menu]}]
+ }
+ right {
+ incr x [expr {[winfo width $button]}]
+ }
+ default {
+ if {[$button cget -indicatoron]} {
+ incr x [expr {([winfo width $button] - \
+ [winfo reqwidth $menu])/ 2}]
+ } else {
+ incr y [winfo height $button]
+ }
+ }
+ }
+ PostOverPoint $menu $x $y $entry
+ }
+}
+
# ::tk::PostOverPoint --
-# This procedure posts a given menu such that a given entry in the
-# menu is centered over a given point in the root window. It also
-# activates the given entry.
+#
+# This procedure posts a menu on the screen so that a given entry in
+# the menu is positioned with its upper left corner at a given point
+# in the root window. The procedure also activates that entry. If no
+# entry is specified the upper left corner of the entire menu is
+# placed at the point.
#
# Arguments:
# menu - Menu to post.
@@ -1220,19 +1247,24 @@ proc ::tk::MenuFindName {menu s} {
# If omitted or specified as {}, then the menu's
# upper-left corner goes at (x,y).
-proc ::tk::PostOverPoint {menu x y {entry {}}} {
- if {$entry ne ""} {
- if {$entry == [$menu index last]} {
- incr y [expr {-([$menu yposition $entry] \
- + [winfo reqheight $menu])/2}]
+if {[tk windowingsystem] ne "win32"} {
+ proc ::tk::PostOverPoint {menu x y {entry {}}} {
+ if {$entry ne ""} {
+ $menu post $x $y $entry
+ if {[$menu entrycget $entry -state] ne "disabled"} {
+ $menu activate $entry
+ GenerateMenuSelect $menu
+ }
} else {
- incr y [expr {-([$menu yposition $entry] \
- + [$menu yposition [expr {$entry+1}]])/2}]
+ $menu post $x $y
}
- incr x [expr {-[winfo reqwidth $menu]/2}]
+ return
}
-
- if {[tk windowingsystem] eq "win32"} {
+} else {
+ proc ::tk::PostOverPoint {menu x y {entry {}}} {
+ if {$entry ne ""} {
+ incr y [expr {-[$menu yposition $entry]}]
+ }
# osVersion is not available in safe interps
set ver 5
if {[info exists ::tcl_platform(osVersion)]} {
@@ -1248,7 +1280,7 @@ proc ::tk::PostOverPoint {menu x y {entry {}}} {
# manager provided with Vista and Windows 7.
if {$ver < 6} {
set yoffset [expr {[winfo screenheight $menu] \
- - $y - [winfo reqheight $menu] - 10}]
+ - $y - [winfo reqheight $menu] - 10}]
if {$yoffset < [winfo vrooty $menu]} {
# The bottom of the menu is offscreen, so adjust upwards
incr y [expr {$yoffset - [winfo vrooty $menu]}]
@@ -1260,11 +1292,11 @@ proc ::tk::PostOverPoint {menu x y {entry {}}} {
set y [winfo vrooty $menu]
}
}
- }
- $menu post $x $y
- if {$entry ne "" && [$menu entrycget $entry -state] ne "disabled"} {
- $menu activate $entry
- GenerateMenuSelect $menu
+ $menu post $x $y
+ if {$entry ne "" && [$menu entrycget $entry -state] ne "disabled"} {
+ $menu activate $entry
+ GenerateMenuSelect $menu
+ }
}
}
diff --git a/library/ttk/altTheme.tcl b/library/ttk/altTheme.tcl
index 6fc76f8..80ef415 100644
--- a/library/ttk/altTheme.tcl
+++ b/library/ttk/altTheme.tcl
@@ -96,10 +96,8 @@ namespace eval ttk::theme::alt {
ttk::style configure Treeview -background $colors(-window)
ttk::style map Treeview \
-background [list disabled $colors(-frame)\
- {!disabled !selected} $colors(-window) \
selected $colors(-selectbg)] \
-foreground [list disabled $colors(-disabledfg) \
- {!disabled !selected} black \
selected $colors(-selectfg)]
ttk::style configure TScale \
diff --git a/library/ttk/aquaTheme.tcl b/library/ttk/aquaTheme.tcl
index d6be5a3..a548d65 100644
--- a/library/ttk/aquaTheme.tcl
+++ b/library/ttk/aquaTheme.tcl
@@ -42,11 +42,9 @@ namespace eval ttk::theme::aqua {
ttk::style configure Treeview -rowheight 18 -background White
ttk::style map Treeview \
-background [list disabled systemDialogBackgroundInactive \
- {!disabled !selected} systemWindowBody \
{selected background} systemHighlightSecondary \
selected systemHighlight] \
-foreground [list disabled systemModelessDialogInactiveText \
- {!disabled !selected} black \
selected systemModelessDialogActiveText]
# Enable animation for ttk::progressbar widget:
diff --git a/library/ttk/clamTheme.tcl b/library/ttk/clamTheme.tcl
index 67e89e6..bfcb194 100644
--- a/library/ttk/clamTheme.tcl
+++ b/library/ttk/clamTheme.tcl
@@ -132,10 +132,8 @@ namespace eval ttk::theme::clam {
ttk::style configure Treeview -background $colors(-window)
ttk::style map Treeview \
-background [list disabled $colors(-frame)\
- {!disabled !selected} $colors(-window) \
selected $colors(-selectbg)] \
-foreground [list disabled $colors(-disabledfg) \
- {!disabled !selected} black \
selected $colors(-selectfg)]
ttk::style configure TLabelframe \
diff --git a/library/ttk/classicTheme.tcl b/library/ttk/classicTheme.tcl
index fefdb99..f237fba 100644
--- a/library/ttk/classicTheme.tcl
+++ b/library/ttk/classicTheme.tcl
@@ -99,10 +99,8 @@ namespace eval ttk::theme::classic {
ttk::style configure Treeview -background $colors(-window)
ttk::style map Treeview \
-background [list disabled $colors(-frame)\
- {!disabled !selected} $colors(-window) \
selected $colors(-selectbg)] \
-foreground [list disabled $colors(-disabledfg) \
- {!disabled !selected} black \
selected $colors(-selectfg)]
#
diff --git a/library/ttk/defaults.tcl b/library/ttk/defaults.tcl
index 5018bf2..2db9a37 100644
--- a/library/ttk/defaults.tcl
+++ b/library/ttk/defaults.tcl
@@ -111,10 +111,8 @@ namespace eval ttk::theme::default {
-foreground $colors(-text) ;
ttk::style map Treeview \
-background [list disabled $colors(-frame)\
- {!disabled !selected} $colors(-window) \
selected $colors(-selectbg)] \
-foreground [list disabled $colors(-disabledfg) \
- {!disabled !selected} black \
selected $colors(-selectfg)]
# Combobox popdown frame
diff --git a/library/ttk/vistaTheme.tcl b/library/ttk/vistaTheme.tcl
index e92345a..165b496 100644
--- a/library/ttk/vistaTheme.tcl
+++ b/library/ttk/vistaTheme.tcl
@@ -48,10 +48,8 @@ namespace eval ttk::theme::vista {
ttk::style configure Treeview -background SystemWindow
ttk::style map Treeview \
-background [list disabled SystemButtonFace \
- {!disabled !selected} SystemWindow \
selected SystemHighlight] \
-foreground [list disabled SystemGrayText \
- {!disabled !selected} SystemWindowText \
selected SystemHighlightText]
# Label and Toolbutton
diff --git a/library/ttk/winTheme.tcl b/library/ttk/winTheme.tcl
index a7a2c79..db05b45 100644
--- a/library/ttk/winTheme.tcl
+++ b/library/ttk/winTheme.tcl
@@ -74,10 +74,8 @@ namespace eval ttk::theme::winnative {
ttk::style configure Treeview -background SystemWindow
ttk::style map Treeview \
-background [list disabled SystemButtonFace \
- {!disabled !selected} SystemWindow \
selected SystemHighlight] \
-foreground [list disabled SystemGrayText \
- {!disabled !selected} SystemWindowText \
selected SystemHighlightText]
ttk::style configure TProgressbar \
diff --git a/library/ttk/xpTheme.tcl b/library/ttk/xpTheme.tcl
index 5d8d09b..4c4f680 100644
--- a/library/ttk/xpTheme.tcl
+++ b/library/ttk/xpTheme.tcl
@@ -67,10 +67,8 @@ namespace eval ttk::theme::xpnative {
ttk::style configure Treeview -background SystemWindow
ttk::style map Treeview \
-background [list disabled SystemButtonFace \
- {!disabled !selected} SystemWindow \
selected SystemHighlight] \
-foreground [list disabled SystemGrayText \
- {!disabled !selected} SystemWindowText \
selected SystemHighlightText];
}
}
diff --git a/macosx/README b/macosx/README
index 6c38dbc..1f5d8a1 100644
--- a/macosx/README
+++ b/macosx/README
@@ -652,7 +652,7 @@ conditional code which is only used for macOS.
10.14 supports system appearance changes, and has added a "Dark Mode"
that casts all window frames and menus as black. Tk 8.6.9 supports Dark
Mode by having the window decorations, menus, and dialogs automatically
-take on the appropriate appearance when the system appearance is changed.
+take on the appropriate appearance when the system appearance is changed.
Because the window content itself is drawn by Tk, it will not change when
the system mode changes.
diff --git a/macosx/tkMacOSXButton.c b/macosx/tkMacOSXButton.c
index ea78d43..c0b83f2 100644
--- a/macosx/tkMacOSXButton.c
+++ b/macosx/tkMacOSXButton.c
@@ -29,19 +29,10 @@
* be allowed when drawing the HITheme button.
*/
-#define HI_PADX 2
+#define HI_PADX 14
#define HI_PADY 1
/*
- * Some defines used to control what type of control is drawn.
- */
-
-#define DRAW_LABEL 0 /* Labels are treated genericly. */
-#define DRAW_CONTROL 1 /* Draw using the Native control. */
-#define DRAW_CUSTOM 2 /* Make our own button drawing. */
-#define DRAW_BEVEL 3
-
-/*
* The delay in milliseconds between pulsing default button redraws.
*/
#define PULSE_TIMER_MSECS 62 /* Largest value that didn't look stuttery */
@@ -52,7 +43,6 @@
typedef struct {
- int drawType;
Tk_3DBorder border;
int relief;
int offset; /* 0 means this is a normal widget. 1 means
@@ -271,11 +261,7 @@ TkpComputeButtonGeometry(
int txtWidth = 0, txtHeight = 0;
MacButton *mbPtr = (MacButton*)butPtr;
Tk_FontMetrics fm;
- DrawParams drawParams;
-
- /*
- * First figure out the size of the contents of the button.
- */
+ char *text = Tcl_GetString(butPtr->textPtr);
TkMacOSXComputeButtonParams(butPtr, &mbPtr->btnkind, &mbPtr->drawinfo);
@@ -283,7 +269,7 @@ TkpComputeButtonGeometry(
* If the indicator is on, get its size.
*/
- if ( butPtr->indicatorOn ) {
+ if (butPtr->indicatorOn) {
switch (butPtr->type) {
case TYPE_RADIO_BUTTON:
GetThemeMetric(kThemeMetricRadioButtonWidth, (SInt32 *)&butPtr->indicatorDiameter);
@@ -309,23 +295,22 @@ TkpComputeButtonGeometry(
haveImage = 1;
}
- if (haveImage == 0 || butPtr->compound != COMPOUND_NONE) {
+ if (strlen(text) > 0) {
Tk_FreeTextLayout(butPtr->textLayout);
butPtr->textLayout = Tk_ComputeTextLayout(butPtr->tkfont,
Tcl_GetString(butPtr->textPtr), -1, butPtr->wrapLength,
butPtr->justify, 0, &butPtr->textWidth, &butPtr->textHeight);
- txtWidth = butPtr->textWidth;
- txtHeight = butPtr->textHeight;
- charWidth = Tk_TextWidth(butPtr->tkfont, "0", 1);
- Tk_GetFontMetrics(butPtr->tkfont, &fm);
- haveText = (txtWidth != 0 && txtHeight != 0);
+ txtWidth = butPtr->textWidth + 2*butPtr->padX;
+ txtHeight = butPtr->textHeight + 2*butPtr->padY;
+ haveText = 1;
}
if (haveImage && haveText) { /* Image and Text */
switch ((enum compound) butPtr->compound) {
case COMPOUND_TOP:
case COMPOUND_BOTTOM:
+
/*
* Image is above or below text.
*/
@@ -335,14 +320,16 @@ TkpComputeButtonGeometry(
break;
case COMPOUND_LEFT:
case COMPOUND_RIGHT:
+
/*
* Image is left or right of text.
*/
- width += txtWidth + butPtr->padX;
+ width += txtWidth + 2*butPtr->padX;
height = (height > txtHeight ? height : txtHeight);
break;
case COMPOUND_CENTER:
+
/*
* Image and text are superimposed.
*/
@@ -354,26 +341,27 @@ TkpComputeButtonGeometry(
break;
}
width += butPtr->indicatorSpace;
-
} else if (haveImage) { /* Image only */
- width = butPtr->width > 0 ? butPtr->width : width + butPtr->indicatorSpace;
- height = butPtr->height > 0 ? butPtr->height : height;
-
+ width = butPtr->width > 0 ? butPtr->width : width + butPtr->indicatorSpace;
+ height = butPtr->height > 0 ? butPtr->height : height;
+ if (butPtr->type == TYPE_BUTTON) {
+ /* Allow room to shift the image. */
+ width += 2;
+ height += 2;
+ }
} else { /* Text only */
width = txtWidth + butPtr->indicatorSpace;
height = txtHeight;
if (butPtr->width > 0) {
- width = butPtr->width * charWidth;
+ charWidth = Tk_TextWidth(butPtr->tkfont, "0", 1);
+ width = butPtr->width * charWidth + 2*butPtr->padX;
}
if (butPtr->height > 0) {
- height = butPtr->height * fm.linespace;
+ Tk_GetFontMetrics(butPtr->tkfont, &fm);
+ height = butPtr->height * fm.linespace + 2*butPtr->padY;
}
}
- /* Add padding */
- width += 2 * butPtr->padX;
- height += 2 * butPtr->padY;
-
/*
* Now figure out the size of the border decorations for the button.
*/
@@ -382,48 +370,35 @@ TkpComputeButtonGeometry(
butPtr->highlightWidth = 0;
}
- butPtr->inset = 0;
- butPtr->inset += butPtr->highlightWidth;
+ butPtr->inset = butPtr->borderWidth + butPtr->highlightWidth;
- if (TkMacOSXComputeButtonDrawParams(butPtr,&drawParams)) {
+ width += butPtr->inset*2;
+ height += butPtr->inset*2;
+ if ([NSApp macMinorVersion] == 6) {
+ width += 12;
+ }
+ if (mbPtr->btnkind == kThemePushButton) {
HIRect tmpRect;
HIRect contBounds;
- int paddingx = 0;
- int paddingy = 0;
+ /*
+ * A PushButton has a minimum size. We make sure that we
+ * are not underestimating the size by requesting the content
+ * size of a Pushbutton whose overall size is our content size
+ * expanded by the standard padding.
+ */
+
tmpRect = CGRectMake(0, 0, width + 2*HI_PADX, height + 2*HI_PADY);
-
HIThemeGetButtonContentBounds(&tmpRect, &mbPtr->drawinfo, &contBounds);
- /* If the content region has a minimum height, match it. */
if (height < contBounds.size.height) {
- height = contBounds.size.height;
+ height = contBounds.size.height;
}
-
- /* If the content region has a minimum width, match it. */
if (width < contBounds.size.width) {
- width = contBounds.size.width;
+ width = contBounds.size.width;
}
-
- /* Pad to fill difference between content bounds and button bounds. */
- paddingx = contBounds.origin.x;
- paddingy = contBounds.origin.y;
-
- if (height < paddingx - 4) {
- /* can't have buttons much shorter than button side diameter. */
- height = paddingx - 4;
- }
-
- } else {
- height += butPtr->borderWidth*2;
- width += butPtr->borderWidth*2;
- }
-
- width += butPtr->inset*2;
- height += butPtr->inset*2;
- if ([NSApp macMinorVersion] == 6) {
- width += 12;
+ height += 2*HI_PADY;
+ width += 2*HI_PADX;
}
-
Tk_GeometryRequest(butPtr->tkwin, width, height);
Tk_SetInternalBorder(butPtr->tkwin, butPtr->inset);
}
@@ -570,7 +545,6 @@ DrawButtonImageAndText(
}
imageXOffset += x;
imageYOffset += y;
- textYOffset -= 1;
if (butPtr->image != NULL) {
if ((butPtr->selectImage != NULL) &&
@@ -594,6 +568,7 @@ DrawButtonImageAndText(
XSetClipOrigin(butPtr->display, dpPtr->gc, 0, 0);
}
+ y += 1; /* Tweak to match native buttons. */
Tk_DrawTextLayout(butPtr->display, pixmap,
dpPtr->gc, butPtr->textLayout,
x + textXOffset, y + textYOffset, 0, -1);
@@ -646,6 +621,7 @@ DrawButtonImageAndText(
butPtr->textWidth + butPtr->indicatorSpace,
butPtr->textHeight, &x, &y);
x += butPtr->indicatorSpace;
+ y += 1; /* Tweak to match native buttons */
Tk_DrawTextLayout(butPtr->display, pixmap, dpPtr->gc, butPtr->textLayout,
x, y, 0, -1);
}
@@ -1119,7 +1095,6 @@ TkMacOSXComputeButtonDrawParams(
}
}
-
dpPtr->border = butPtr->normalBorder;
if ((butPtr->state == STATE_DISABLED) && (butPtr->disabledFg != NULL)) {
dpPtr->gc = butPtr->disabledGC;
@@ -1149,29 +1124,22 @@ TkMacOSXComputeButtonDrawParams(
}
}
- /*
- * Determine the draw type
- */
-
- if (butPtr->type == TYPE_LABEL) {
- dpPtr->drawType = DRAW_LABEL;
- } else if (butPtr->type == TYPE_BUTTON) {
- if (!dpPtr->hasImageOrBitmap) {
- dpPtr->drawType = DRAW_CONTROL;
- } else {
- dpPtr->drawType = DRAW_BEVEL;
- }
- } else if (butPtr->indicatorOn) {
- dpPtr->drawType = DRAW_CONTROL;
- } else if (dpPtr->hasImageOrBitmap) {
- dpPtr->drawType = DRAW_BEVEL;
- } else {
- dpPtr->drawType = DRAW_CUSTOM;
- }
-
- if ((dpPtr->drawType == DRAW_CONTROL) || (dpPtr->drawType == DRAW_BEVEL)) {
+ if (butPtr->type != TYPE_LABEL &&
+ (butPtr->type == TYPE_BUTTON ||
+ butPtr->indicatorOn ||
+ dpPtr->hasImageOrBitmap)) {
+
+ /*
+ * Draw this widget as a native control.
+ */
+
return 1;
} else {
+
+ /*
+ * Draw this widget from scratch.
+ */
+
return 0;
}
}
diff --git a/macosx/tkMacOSXDefault.h b/macosx/tkMacOSXDefault.h
index ce41751..f5ffbbf 100644
--- a/macosx/tkMacOSXDefault.h
+++ b/macosx/tkMacOSXDefault.h
@@ -37,7 +37,7 @@
#define ACTIVE_BG "systemButtonFacePressed"
#define ACTIVE_FG "systemPushButtonPressedText"
#define SELECT_BG "systemHighlight"
-#define SELECT_FG None
+#define SELECT_FG NULL
#define INACTIVE_SELECT_BG "systemHighlightSecondary"
#define TROUGH "#c3c3c3"
#define INDICATOR "#b03060"
@@ -284,7 +284,7 @@
#define DEF_MENU_ENTRY_ACTIVE_FG NULL
#define DEF_MENU_ENTRY_ACCELERATOR NULL
#define DEF_MENU_ENTRY_BG NULL
-#define DEF_MENU_ENTRY_BITMAP None
+#define DEF_MENU_ENTRY_BITMAP NULL
#define DEF_MENU_ENTRY_COLUMN_BREAK "0"
#define DEF_MENU_ENTRY_COMMAND NULL
#define DEF_MENU_ENTRY_COMPOUND "none"
@@ -337,7 +337,7 @@
* Defaults for menubuttons:
*/
-#define DEF_MENUBUTTON_ANCHOR "center"
+#define DEF_MENUBUTTON_ANCHOR "w"
#define DEF_MENUBUTTON_ACTIVE_BG_COLOR ACTIVE_BG
#define DEF_MENUBUTTON_ACTIVE_BG_MONO BLACK
#define DEF_MENUBUTTON_ACTIVE_FG_COLOR ACTIVE_FG
@@ -345,7 +345,7 @@
#define DEF_MENUBUTTON_BG_COLOR NORMAL_BG
#define DEF_MENUBUTTON_BG_MONO WHITE
#define DEF_MENUBUTTON_BITMAP ""
-#define DEF_MENUBUTTON_BORDER_WIDTH "2"
+#define DEF_MENUBUTTON_BORDER_WIDTH "0"
#define DEF_MENUBUTTON_CURSOR ""
#define DEF_MENUBUTTON_DIRECTION "below"
#define DEF_MENUBUTTON_DISABLED_FG_COLOR DISABLED
@@ -361,8 +361,8 @@
#define DEF_MENUBUTTON_INDICATOR "1"
#define DEF_MENUBUTTON_JUSTIFY "left"
#define DEF_MENUBUTTON_MENU ""
-#define DEF_MENUBUTTON_PADX "4"
-#define DEF_MENUBUTTON_PADY "3"
+#define DEF_MENUBUTTON_PADX "0"
+#define DEF_MENUBUTTON_PADY "0"
#define DEF_MENUBUTTON_RELIEF "flat"
#define DEF_MENUBUTTON_STATE "normal"
#define DEF_MENUBUTTON_TAKE_FOCUS "0"
diff --git a/macosx/tkMacOSXDialog.c b/macosx/tkMacOSXDialog.c
index e828b39..c3778f1 100644
--- a/macosx/tkMacOSXDialog.c
+++ b/macosx/tkMacOSXDialog.c
@@ -1194,12 +1194,12 @@ TkAboutDlg(void)
NSString *year = [dateFormatter stringFromDate:[NSDate date]];
[dateFormatter release];
-
+
/*
* This replaces the old about dialog with a standard alert that displays
* correctly on 10.14.
*/
-
+
NSString *version = @"Tcl " TCL_PATCH_LEVEL " & Tk " TCL_PATCH_LEVEL;
NSString *url = @"www.tcl-lang.org";
NSTextView *credits = [[NSTextView alloc] initWithFrame:NSMakeRect(0,0,300,300)];
diff --git a/macosx/tkMacOSXEmbed.c b/macosx/tkMacOSXEmbed.c
index 05bf832..b23f33b 100644
--- a/macosx/tkMacOSXEmbed.c
+++ b/macosx/tkMacOSXEmbed.c
@@ -272,7 +272,14 @@ TkpUseWindow(
}
usePtr = (TkWindow *) Tk_IdToWindow(winPtr->display, (Window) parent);
- if (usePtr != NULL && !(usePtr->flags & TK_CONTAINER)) {
+ if (usePtr == NULL) {
+ if (interp != NULL) {
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "couldn't create child of window \"%s\"", string));
+ Tcl_SetErrorCode(interp, "TK", "EMBED", "NO_TARGET", NULL);
+ }
+ return TCL_ERROR;
+ } else if (!(usePtr->flags & TK_CONTAINER)) {
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"window \"%s\" doesn't have -container option set",
usePtr->pathName));
@@ -281,15 +288,9 @@ TkpUseWindow(
}
/*
- * The code below can probably be simplified given we have already
- * discovered 'usePtr' above.
- */
-
- /*
- * Save information about the container and the embedded window in a
- * Container structure. Currently, there must already be an existing
- * Container structure, since we only allow the case where both container
- * and embedded app. are in the same process.
+ * Since we do not allow embedding into windows belonging to a different
+ * process, we know that a container will exist showing the parent window
+ * as the parent. This loop finds that container.
*/
for (containerPtr = firstContainerPtr; containerPtr != NULL;
@@ -312,16 +313,6 @@ TkpUseWindow(
}
macWin->winPtr = winPtr;
- winPtr->privatePtr = macWin;
-
- /*
- * The grafPtr will be NULL for a Tk in Tk embedded window. It is none of
- * our business what it is for a Tk not in Tk embedded window, but we will
- * initialize it to NULL, and let the registerWinProc set it. In any case,
- * you must always use TkMacOSXGetDrawablePort to get the portPtr. It will
- * correctly find the container's port.
- */
-
macWin->view = nil;
macWin->context = NULL;
macWin->size = CGSizeZero;
@@ -333,6 +324,7 @@ TkpUseWindow(
macWin->toplevel = macWin;
macWin->toplevel->referenceCount++;
+ winPtr->privatePtr = macWin;
winPtr->flags |= TK_EMBEDDED;
/*
@@ -341,64 +333,28 @@ TkpUseWindow(
*/
macWin->flags |= TK_EMBEDDED;
+ macWin->xOff = parent->winPtr->privatePtr->xOff +
+ parent->winPtr->changes.border_width +
+ winPtr->changes.x;
+ macWin->yOff = parent->winPtr->privatePtr->yOff +
+ parent->winPtr->changes.border_width +
+ winPtr->changes.y;
/*
- * Now check whether it is embedded in another Tk widget. If not (the
- * first case below) we see if there is an in-process embedding handler
- * registered, and if so, let that fill in the rest of the macWin.
+ * Finish filling up the container structure with the embedded
+ * window's information.
*/
- if (containerPtr == NULL) {
- /*
- * If someone has registered an in-process embedding handler, then
- * see if it can handle this window...
- */
-
- if (tkMacOSXEmbedHandler == NULL ||
- tkMacOSXEmbedHandler->registerWinProc((long) parent,
- (Tk_Window) winPtr) != TCL_OK) {
- Tcl_SetObjResult(interp, Tcl_ObjPrintf(
- "The window ID %s does not correspond to a valid Tk Window",
- string));
- Tcl_SetErrorCode(interp, "TK", "EMBED", "HANDLE", NULL);
- return TCL_ERROR;
- }
-
- containerPtr = ckalloc(sizeof(Container));
-
- containerPtr->parentPtr = NULL;
- containerPtr->embedded = (Window) macWin;
- containerPtr->embeddedPtr = macWin->winPtr;
- containerPtr->nextPtr = firstContainerPtr;
- firstContainerPtr = containerPtr;
- } else {
- /*
- * The window is embedded in another Tk window.
- */
+ containerPtr->embedded = (Window) macWin;
+ containerPtr->embeddedPtr = macWin->winPtr;
- macWin->xOff = parent->winPtr->privatePtr->xOff +
- parent->winPtr->changes.border_width +
- winPtr->changes.x;
- macWin->yOff = parent->winPtr->privatePtr->yOff +
- parent->winPtr->changes.border_width +
- winPtr->changes.y;
-
- /*
- * Finish filling up the container structure with the embedded
- * window's information.
- */
-
- containerPtr->embedded = (Window) macWin;
- containerPtr->embeddedPtr = macWin->winPtr;
-
- /*
- * Create an event handler to clean up the Container structure when
- * tkwin is eventually deleted.
- */
+ /*
+ * Create an event handler to clean up the Container structure when
+ * tkwin is eventually deleted.
+ */
- Tk_CreateEventHandler(tkwin, StructureNotifyMask, EmbeddedEventProc,
- winPtr);
- }
+ Tk_CreateEventHandler(tkwin, StructureNotifyMask, EmbeddedEventProc,
+ winPtr);
return TCL_OK;
}
@@ -494,7 +450,7 @@ TkMacOSXContainerId(
}
}
Tcl_Panic("TkMacOSXContainerId couldn't find window");
- return None;
+ return NULL;
}
/*
@@ -530,8 +486,8 @@ TkMacOSXGetHostToplevel(
* TODO: Here we should handle out of process embedding.
*/
- if (contWinPtr == NULL) {
- return None;
+ if (!contWinPtr) {
+ return NULL;
}
return TkMacOSXGetHostToplevel(contWinPtr);
}
@@ -542,9 +498,7 @@ TkMacOSXGetHostToplevel(
* TkpClaimFocus --
*
* This procedure is invoked when someone asks for the input focus to be
- * put on a window in an embedded application, but the application
- * doesn't currently have the focus. It requests the input focus from the
- * container application.
+ * put on a window in an embedded application.
*
* Results:
* None.
@@ -583,7 +537,7 @@ TkpClaimFocus(
event.xfocus.window = containerPtr->parent;
event.xfocus.mode = EMBEDDED_APP_WANTS_FOCUS;
event.xfocus.detail = force;
- Tk_QueueWindowEvent(&event,TCL_QUEUE_TAIL);
+ Tk_HandleEvent(&event);
}
/*
@@ -614,6 +568,7 @@ TkpTestembedCmd(
Container *containerPtr;
Tcl_DString dString;
char buffer[50];
+ Tcl_Interp *embeddedInterp = NULL, *parentInterp = NULL;
if ((objc > 1) && (strcmp(Tcl_GetString(objv[1]), "all") == 0)) {
all = 1;
@@ -623,7 +578,17 @@ TkpTestembedCmd(
Tcl_DStringInit(&dString);
for (containerPtr = firstContainerPtr; containerPtr != NULL;
containerPtr = containerPtr->nextPtr) {
+ if (containerPtr->embeddedPtr != NULL) {
+ embeddedInterp = containerPtr->embeddedPtr->mainPtr->interp;
+ }
+ if (containerPtr->parentPtr != NULL) {
+ parentInterp = containerPtr->parentPtr->mainPtr->interp;
+ }
+ if (embeddedInterp != interp && parentInterp != interp) {
+ continue;
+ }
Tcl_DStringStartSublist(&dString);
+ /* Parent id */
if (containerPtr->parent == None) {
Tcl_DStringAppendElement(&dString, "");
} else if (all) {
@@ -632,21 +597,21 @@ TkpTestembedCmd(
} else {
Tcl_DStringAppendElement(&dString, "XXX");
}
- if (containerPtr->parentPtr == NULL) {
+ /* Parent pathName */
+ if (containerPtr->parentPtr == NULL ||
+ parentInterp != interp) {
Tcl_DStringAppendElement(&dString, "");
} else {
Tcl_DStringAppendElement(&dString,
containerPtr->parentPtr->pathName);
}
- if (containerPtr->embedded == None) {
- Tcl_DStringAppendElement(&dString, "");
- } else if (all) {
- sprintf(buffer, "0x%" TCL_Z_MODIFIER "x", (size_t) containerPtr->embedded);
- Tcl_DStringAppendElement(&dString, buffer);
- } else {
- Tcl_DStringAppendElement(&dString, "XXX");
- }
- if (containerPtr->embeddedPtr == NULL) {
+ /*
+ * On X11 embedded is a wrapper, which does not exist on macOS.
+ */
+ Tcl_DStringAppendElement(&dString, "");
+ /* Embedded window pathName */
+ if (containerPtr->embeddedPtr == NULL ||
+ embeddedInterp != interp) {
Tcl_DStringAppendElement(&dString, "");
} else {
Tcl_DStringAppendElement(&dString,
@@ -904,6 +869,14 @@ EmbedStructureProc(
Tk_ErrorHandler errHandler;
if (eventPtr->type == ConfigureNotify) {
+
+ /*
+ * Send a ConfigureNotify to the embedded application.
+ */
+
+ if (containerPtr->embeddedPtr != None) {
+ TkDoConfigureNotify(containerPtr->embeddedPtr);
+ }
if (containerPtr->embedded != None) {
/*
* Ignore errors, since the embedded application could have
@@ -947,7 +920,6 @@ EmbedActivateProc(
XEvent *eventPtr) /* ResizeRequest event. */
{
Container *containerPtr = clientData;
-
if (containerPtr->embeddedPtr != NULL) {
if (eventPtr->type == ActivateNotify) {
TkGenerateActivateEvents(containerPtr->embeddedPtr,1);
diff --git a/macosx/tkMacOSXEntry.c b/macosx/tkMacOSXEntry.c
index 4ab3111..a1c5d60 100644
--- a/macosx/tkMacOSXEntry.c
+++ b/macosx/tkMacOSXEntry.c
@@ -156,10 +156,10 @@ TkpDrawEntryBorderAndFocus(
bounds.size.height = Tk_Height(tkwin) - 2*MAC_OSX_FOCUS_WIDTH;
if (!TkMacOSXSetupDrawingContext(d, NULL, 1, &dc)) {
- /*
+ /*
* No graphics context is available. If the widget is a Spinbox, we
* must restore its width before returning 0. (Ticket [273b6a4996].)
- */
+ */
if (isSpinbox) {
Tk_Width(tkwin) = oldWidth;
diff --git a/macosx/tkMacOSXEvent.c b/macosx/tkMacOSXEvent.c
index d866b02..b9c9b6a 100644
--- a/macosx/tkMacOSXEvent.c
+++ b/macosx/tkMacOSXEvent.c
@@ -114,21 +114,16 @@ enum {
*
* This routine is a stub called by XSync, which is called during the Tk
* update command. The language specification does not require that the
- * update command be synchronous but many of the tests assume that is the
- * case. It is not naturally the case on macOS since many idle tasks are
- * run inside of the drawRect method of a window's contentView, and that
- * method will not be called until after this function returns. To make
- * the tests work, we attempt to force this to be synchronous by waiting
- * until drawRect has been called for each window. The mechanism we use
- * for this is to have drawRect post an ApplicationDefined NSEvent on the
- * AppKit event queue when it finishes drawing, and wait for it here.
+ * update command be synchronous but many of the tests implicitly assume
+ * that it is. It is definitely asynchronous on macOS since many idle
+ * tasks are run inside of the drawRect method of a window's contentView,
+ * which will not be called until after this function returns.
*
* Results:
* None.
*
- * Side effects:
- * Calls the drawRect method of the contentView of each visible
- * window.
+ * Side effects: Processes all pending idle events then calls the display
+ * method of each visible window.
*
*----------------------------------------------------------------------
*/
@@ -136,23 +131,12 @@ enum {
MODULE_SCOPE void
TkMacOSXFlushWindows(void)
{
- NSArray *macWindows = [NSApp orderedWindows];
-
- if ([macWindows count] > 0) {
- while (Tcl_DoOneEvent(TCL_IDLE_EVENTS)){}
+ if (Tk_GetNumMainWindows() == 0) {
+ return;
}
- if ([NSApp isDrawing]) {
- for (NSWindow *w in macWindows) {
- if (TkMacOSXGetXWindow(w)) {
- [w setViewsNeedDisplay:YES];
- }
- }
- } else {
- for (NSWindow *w in macWindows) {
- if (TkMacOSXGetXWindow(w)) {
- [w display];
- }
- }
+ while (Tcl_DoOneEvent(TCL_IDLE_EVENTS)){}
+ for (NSWindow *w in [NSApp orderedWindows]) {
+ [w display];
}
}
diff --git a/macosx/tkMacOSXImage.c b/macosx/tkMacOSXImage.c
index 0c9fcb3..38f4a70 100644
--- a/macosx/tkMacOSXImage.c
+++ b/macosx/tkMacOSXImage.c
@@ -100,7 +100,7 @@ TkMacOSXCreateCGImageWithXImage(
/*
* CGCreateImage complains on early macOS releases.
*/
-
+
return NULL;
}
bitsPerComponent = 8;
diff --git a/macosx/tkMacOSXInit.c b/macosx/tkMacOSXInit.c
index 65534ae..3c02d92 100644
--- a/macosx/tkMacOSXInit.c
+++ b/macosx/tkMacOSXInit.c
@@ -121,7 +121,17 @@ static char scriptPath[PATH_MAX + 1] = "";
* method is called. Activating too early can cause the menu
* bar to be unresponsive.
*/
+
[NSApp activateIgnoringOtherApps: YES];
+
+ /*
+ * Process events to ensure that the root window is fully
+ * initialized. See ticket 56a1823c73.
+ */
+
+ [NSApp _lockAutoreleasePool];
+ while (Tcl_DoOneEvent(TCL_WINDOW_EVENTS| TCL_DONT_WAIT)) {}
+ [NSApp _unlockAutoreleasePool];
}
- (void) _setup: (Tcl_Interp *) interp
@@ -373,7 +383,7 @@ TkpInit(
* if displayed before main window. This places console in background and it
* accepts input after being raised.
*/
-
+
while (Tcl_DoOneEvent(TCL_IDLE_EVENTS)) {}
return TCL_OK;
diff --git a/macosx/tkMacOSXKeyEvent.c b/macosx/tkMacOSXKeyEvent.c
index a153797..543e7ab 100644
--- a/macosx/tkMacOSXKeyEvent.c
+++ b/macosx/tkMacOSXKeyEvent.c
@@ -24,9 +24,6 @@
*/
#define NS_KEYLOG 0
-
-static Tk_Window grabWinPtr = NULL;
- /* Current grab window, NULL if no grab. */
static Tk_Window keyboardGrabWinPtr = NULL;
/* Current keyboard grab window. */
static NSWindow *keyboardGrabNSWindow = nil;
@@ -139,18 +136,26 @@ unsigned short releaseCode;
}
/*
- * The focus must be in the FrontWindow on the Macintosh. We then query Tk
- * to determine the exact Tk window that owns the focus.
+ * Events are only received for the front Window on the Macintosh.
+ * So to build an XEvent we look up the Tk window associated to the
+ * Front window. If a different window has a local grab we ignore
+ * the event.
*/
TkWindow *winPtr = TkMacOSXGetTkWindow(w);
Tk_Window tkwin = (Tk_Window) winPtr;
- if (!tkwin) {
- TkMacOSXDbgMsg("tkwin == NULL");
- return theEvent;
- }
- tkwin = (Tk_Window) winPtr->dispPtr->focusPtr;
+ 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 = (Tk_Window) winPtr->dispPtr->focusPtr;
+ }
if (!tkwin) {
TkMacOSXDbgMsg("tkwin == NULL");
return theEvent; /* Give up. No window for this event. */
@@ -160,6 +165,7 @@ unsigned short releaseCode;
* If it's a function key, or we have modifiers other than Shift or Alt,
* pass it straight to Tk. Otherwise we'll send for input processing.
*/
+
int code = (len == 0) ?
0 : [charactersIgnoringModifiers characterAtIndex: 0];
if (type != NSKeyDown || isFunctionKey(code)
@@ -491,11 +497,12 @@ XGrabKeyboard(
Time time)
{
keyboardGrabWinPtr = Tk_IdToWindow(display, grab_window);
- if (keyboardGrabWinPtr && grabWinPtr) {
+ TkWindow *captureWinPtr = (TkWindow *)TkMacOSXGetCapture();
+ if (keyboardGrabWinPtr && captureWinPtr) {
NSWindow *w = TkMacOSXDrawableWindow(grab_window);
MacDrawable *macWin = (MacDrawable *) grab_window;
- if (w && macWin->toplevel->winPtr == (TkWindow*) grabWinPtr) {
+ if (w && macWin->toplevel->winPtr == (TkWindow*) captureWinPtr) {
if (modalSession) {
Tcl_Panic("XGrabKeyboard: already grabbed");
}
@@ -542,26 +549,6 @@ XUngrabKeyboard(
/*
*----------------------------------------------------------------------
*
- * TkMacOSXGetCapture --
- *
- * Results:
- * Returns the current grab window
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
-
-Tk_Window
-TkMacOSXGetCapture(void)
-{
- return grabWinPtr;
-}
-
-/*
- *----------------------------------------------------------------------
- *
* TkMacOSXGetModalSession --
*
* Results:
@@ -582,34 +569,6 @@ TkMacOSXGetModalSession(void)
/*
*----------------------------------------------------------------------
*
- * TkpSetCapture --
- *
- * This function captures the mouse so that all future events will be
- * reported to this window, even if the mouse is outside the window. If
- * the specified window is NULL, then the mouse is released.
- *
- * Results:
- * None.
- *
- * Side effects:
- * Sets the capture flag and captures the mouse.
- *
- *----------------------------------------------------------------------
- */
-
-void
-TkpSetCapture(
- TkWindow *winPtr) /* Capture window, or NULL. */
-{
- while (winPtr && !Tk_IsTopLevel(winPtr)) {
- winPtr = winPtr->parentPtr;
- }
- grabWinPtr = (Tk_Window) winPtr;
-}
-
-/*
- *----------------------------------------------------------------------
- *
* Tk_SetCaretPos --
*
* This enables correct placement of the XIM caret. This is called by
diff --git a/macosx/tkMacOSXMenu.c b/macosx/tkMacOSXMenu.c
index ec32a78..227c379 100644
--- a/macosx/tkMacOSXMenu.c
+++ b/macosx/tkMacOSXMenu.c
@@ -755,10 +755,13 @@ TkpDestroyMenuEntry(
*
* TkpPostMenu --
*
- * Posts a menu on the screen
+ * Posts a menu on the screen. If entry is < 0 then the menu is
+ * drawn so its top left corner is located at the point with
+ * screen coordinates (x, y). Otherwise the top left corner of
+ * the specified entry is located at that point.
*
* Results:
- * None.
+ * Returns a standard Tcl result.
*
* Side effects:
* The menu is posted and handled.
@@ -770,50 +773,52 @@ int
TkpPostMenu(
Tcl_Interp *interp, /* The interpreter this menu lives in */
TkMenu *menuPtr, /* The menu we are posting */
- int x, /* The global x-coordinate of the top, left-
- * hand corner of where the menu is supposed
- * to be posted. */
- int y) /* The global y-coordinate */
+ int x, int y, /* The screen coordinates where the top left
+ * corner of the menu, or of the specified
+ * entry, will be located. */
+ int index)
{
+ int result;
+ Tk_Window root = Tk_MainWindow(interp);
-
- /* Get the object that holds this Tk Window.*/
- Tk_Window root;
- root = Tk_MainWindow(interp);
if (root == NULL) {
return TCL_ERROR;
}
-
Drawable d = Tk_WindowId(root);
NSView *rootview = TkMacOSXGetRootControl(d);
NSWindow *win = [rootview window];
- int result;
+ NSView *view = [win contentView];
+ NSMenu *menu = (NSMenu *) menuPtr->platformData;
+ NSInteger itemIndex = index;
+ NSInteger numItems = [menu numberOfItems];
+ NSMenuItem *item = nil;
+ NSPoint location = NSMakePoint(x, tkMacOSXZeroScreenHeight - y);
inPostMenu = 1;
-
result = TkPreprocessMenu(menuPtr);
if (result != TCL_OK) {
inPostMenu = 0;
return result;
}
+ if (itemIndex >= numItems) {
+ itemIndex = numItems - 1;
+ }
+ if (itemIndex >= 0) {
+ item = [menu itemAtIndex:itemIndex];
+ }
+
+ /*
+ * The post commands could have deleted the menu, which means we are dead
+ * and should go away.
+ */
- int oldMode = Tcl_SetServiceMode(TCL_SERVICE_NONE);
- NSView *view = [win contentView];
- NSRect frame = NSMakeRect(x + 9, tkMacOSXZeroScreenHeight - y - 9, 1, 1);
-
- frame.origin = [view convertPoint:
- [win tkConvertPointFromScreen:frame.origin] fromView:nil];
+ if (menuPtr->tkwin == NULL) {
+ return TCL_OK;
+ }
- NSMenu *menu = (NSMenu *) menuPtr->platformData;
- NSPopUpButtonCell *popUpButtonCell = [[NSPopUpButtonCell alloc]
- initTextCell:@"" pullsDown:NO];
-
- [popUpButtonCell setAltersStateOfSelectedItem:NO];
- [popUpButtonCell setMenu:menu];
- [popUpButtonCell selectItem:nil];
- [popUpButtonCell performClickWithFrame:frame inView:view];
- [popUpButtonCell release];
- Tcl_SetServiceMode(oldMode);
+ [menu popUpMenuPositioningItem:item
+ atLocation:[win tkConvertPointFromScreen:location]
+ inView:view];
inPostMenu = 0;
return TCL_OK;
}
@@ -821,6 +826,109 @@ TkpPostMenu(
/*
*----------------------------------------------------------------------
*
+ * TkpPostTearoffMenu --
+ *
+ * Tearoff menus are not supported on the Mac. This placeholder
+ * function, which is simply a copy of the unix function, posts a
+ * completely useless window with a black background on the screen. If
+ * entry is < 0 then the window is positioned so that its top left corner
+ * is located at the point with screen coordinates (x, y). Otherwise the
+ * window position is offset so that top left corner of the specified
+ * entry would be located at that point, if there actually were a menu.
+ *
+ * Mac menus steal all mouse or keyboard input from the application until
+ * the menu is dismissed, with or without a selection, by a mouse or key
+ * event. Posting a Mac menu in a regression test will cause the test to
+ * halt waiting for user input. This is why the TkpPostMenu function is
+ * not being used as the placeholder.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * A useless window is posted.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TkpPostTearoffMenu(
+ Tcl_Interp *interp, /* The interpreter this menu lives in */
+ TkMenu *menuPtr, /* The menu we are posting */
+ int x, int y, int index) /* The screen coordinates where the top left
+ * corner of the menu, or of the specified
+ * entry, will be located. */
+{
+ int vRootX, vRootY, vRootWidth, vRootHeight;
+ int result;
+
+ if (index >= menuPtr->numEntries) {
+ index = menuPtr->numEntries - 1;
+ }
+ if (index >= 0) {
+ y -= menuPtr->entries[index]->y;
+ }
+
+ TkActivateMenuEntry(menuPtr, -1);
+ TkRecomputeMenu(menuPtr);
+ result = TkPostCommand(menuPtr);
+ if (result != TCL_OK) {
+ return result;
+ }
+
+ /*
+ * The post commands could have deleted the menu, which means we are dead
+ * and should go away.
+ */
+
+ if (menuPtr->tkwin == NULL) {
+ return TCL_OK;
+ }
+
+ /*
+ * Adjust the position of the menu if necessary to keep it visible on the
+ * screen. There are two special tricks to make this work right:
+ *
+ * 1. If a virtual root window manager is being used then the coordinates
+ * are in the virtual root window of menuPtr's parent; since the menu
+ * uses override-redirect mode it will be in the *real* root window for
+ * the screen, so we have to map the coordinates from the virtual root
+ * (if any) to the real root. Can't get the virtual root from the menu
+ * itself (it will never be seen by the wm) so use its parent instead
+ * (it would be better to have an an option that names a window to use
+ * for this...).
+ * 2. The menu may not have been mapped yet, so its current size might be
+ * the default 1x1. To compute how much space it needs, use its
+ * requested size, not its actual size.
+ */
+
+ Tk_GetVRootGeometry(Tk_Parent(menuPtr->tkwin), &vRootX, &vRootY,
+ &vRootWidth, &vRootHeight);
+ vRootWidth -= Tk_ReqWidth(menuPtr->tkwin);
+ if (x > vRootX + vRootWidth) {
+ x = vRootX + vRootWidth;
+ }
+ if (x < vRootX) {
+ x = vRootX;
+ }
+ vRootHeight -= Tk_ReqHeight(menuPtr->tkwin);
+ if (y > vRootY + vRootHeight) {
+ y = vRootY + vRootHeight;
+ }
+ if (y < vRootY) {
+ y = vRootY;
+ }
+ Tk_MoveToplevelWindow(menuPtr->tkwin, x, y);
+ if (!Tk_IsMapped(menuPtr->tkwin)) {
+ Tk_MapWindow(menuPtr->tkwin);
+ }
+ TkWmRestackToplevel((TkWindow *) menuPtr->tkwin, Above, NULL);
+ return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
* TkpSetWindowMenuBar --
*
* Associates a given menu with a window.
@@ -877,26 +985,47 @@ TkpSetMainMenubar(
{
static Tcl_Interp *currentInterp = NULL;
TKMenu *menu = nil;
+ TkWindow *winPtr = (TkWindow *) tkwin;
+
+ /*
+ * We will be called when an embedded window receives an ActivationNotify
+ * event, but we should not change the menubar in that case.
+ */
+
+ if (Tk_IsEmbedded(winPtr)) {
+ return;
+ }
if (menuName) {
- TkWindow *winPtr = (TkWindow *) tkwin;
+ Tk_Window menubar = NULL;
+ if (winPtr->wmInfoPtr &&
+ winPtr->wmInfoPtr->menuPtr &&
+ winPtr->wmInfoPtr->menuPtr->masterMenuPtr) {
+ menubar = winPtr->wmInfoPtr->menuPtr->masterMenuPtr->tkwin;
+ }
+
+ /*
+ * Attempt to find the NSMenu directly. If that fails, ask Tk to find it.
+ */
- if (winPtr->wmInfoPtr && winPtr->wmInfoPtr->menuPtr &&
- winPtr->wmInfoPtr->menuPtr->masterMenuPtr &&
- winPtr->wmInfoPtr->menuPtr->masterMenuPtr->tkwin &&
- !strcmp(menuName, Tk_PathName(
- winPtr->wmInfoPtr->menuPtr->masterMenuPtr->tkwin))) {
+ if (menubar != NULL && strcmp(menuName, Tk_PathName(menubar)) == 0) {
menu = (TKMenu *) winPtr->wmInfoPtr->menuPtr->platformData;
} else {
TkMenuReferences *menuRefPtr = TkFindMenuReferences(interp,
menuName);
-
if (menuRefPtr && menuRefPtr->menuPtr &&
menuRefPtr->menuPtr->platformData) {
menu = (TKMenu *) menuRefPtr->menuPtr->platformData;
}
}
}
+
+ /*
+ * If we couldn't find a menu, do nothing unless the window belongs
+ * to a different application. In that case, install the default
+ * menubar.
+ */
+
if (menu || interp != currentInterp) {
[NSApp tkSetMainMenu:menu];
}
@@ -909,8 +1038,8 @@ TkpSetMainMenubar(
* CheckForSpecialMenu --
*
* Given a menu, check to see whether or not it is a cascade in a menubar
- * with one of the special names .apple, .help or .window If it is, the
- * entry that points to this menu will be marked.
+ * with one of the special names ".apple", ".help" or ".window". If it
+ * is, the entry that points to this menu will be marked.
*
* Results:
* None.
@@ -1087,26 +1216,31 @@ void
TkpComputeStandardMenuGeometry(
TkMenu *menuPtr) /* Structure describing menu. */
{
+ NSSize menuSize;
Tk_Font tkfont, menuFont;
Tk_FontMetrics menuMetrics, entryMetrics, *fmPtr;
int modifierCharWidth, menuModifierCharWidth;
int x, y, modifierWidth, labelWidth, indicatorSpace;
int windowWidth, windowHeight, accelWidth;
- int i, j, lastColumnBreak, maxWidth;
+ int i, maxWidth;
int entryWidth, maxIndicatorSpace, borderWidth, activeBorderWidth;
- TkMenuEntry *mePtr, *columnEntryPtr;
+ TkMenuEntry *mePtr;
int haveAccel = 0;
- if (menuPtr->tkwin == NULL) {
+ /*
+ * Do nothing if this menu is a clone.
+ */
+ if (menuPtr->tkwin == NULL || menuPtr->masterMenuPtr != menuPtr) {
return;
}
-
+
+ menuSize = [(NSMenu *)menuPtr->platformData size];
Tk_GetPixelsFromObj(NULL, menuPtr->tkwin, menuPtr->borderWidthPtr,
&borderWidth);
Tk_GetPixelsFromObj(NULL, menuPtr->tkwin, menuPtr->activeBorderWidthPtr,
&activeBorderWidth);
x = y = borderWidth;
- windowHeight = maxWidth = lastColumnBreak = 0;
+ windowHeight = maxWidth = 0;
maxIndicatorSpace = 0;
/*
@@ -1133,6 +1267,9 @@ TkpComputeStandardMenuGeometry(
for (i = 0; i < menuPtr->numEntries; i++) {
mePtr = menuPtr->entries[i];
+ if (mePtr->type == TEAROFF_ENTRY) {
+ continue;
+ }
if (mePtr->fontPtr == NULL) {
tkfont = menuFont;
fmPtr = &menuMetrics;
@@ -1143,26 +1280,8 @@ TkpComputeStandardMenuGeometry(
fmPtr = &entryMetrics;
modifierCharWidth = ModifierCharWidth(tkfont);
}
-
- if ((i > 0) && mePtr->columnBreak) {
- if (maxIndicatorSpace != 0) {
- maxIndicatorSpace += 2;
- }
- for (j = lastColumnBreak; j < i; j++) {
- columnEntryPtr = menuPtr->entries[j];
- columnEntryPtr->indicatorSpace = maxIndicatorSpace;
- columnEntryPtr->width = maxIndicatorSpace + maxWidth
- + 2 * activeBorderWidth;
- columnEntryPtr->x = x;
- columnEntryPtr->entryFlags &= ~ENTRY_LAST_COLUMN;
- }
- x += maxIndicatorSpace + maxWidth + 2 * activeBorderWidth;
- maxWidth = maxIndicatorSpace = 0;
- lastColumnBreak = i;
- y = borderWidth;
- }
accelWidth = modifierWidth = indicatorSpace = 0;
- if (mePtr->type == SEPARATOR_ENTRY || mePtr->type == TEAROFF_ENTRY) {
+ if (mePtr->type == SEPARATOR_ENTRY) {
mePtr->height = menuSeparatorHeight;
} else {
/*
@@ -1176,16 +1295,16 @@ TkpComputeStandardMenuGeometry(
NSMenuItem *menuItem = (NSMenuItem *) mePtr->platformEntryData;
int haveImage = 0, width = 0, height = 0;
-
if (mePtr->image) {
Tk_SizeOfImage(mePtr->image, &width, &height);
haveImage = 1;
+ height += 2; /* tweak */
} else if (mePtr->bitmapPtr) {
Pixmap bitmap = Tk_GetBitmapFromObj(menuPtr->tkwin,
mePtr->bitmapPtr);
-
Tk_SizeOfBitmap(menuPtr->display, bitmap, &width, &height);
haveImage = 1;
+ height += 2; /* tweak */
}
if (!haveImage || (mePtr->compound != COMPOUND_NONE)) {
NSAttributedString *attrTitle = [menuItem attributedTitle];
@@ -1197,11 +1316,8 @@ TkpComputeStandardMenuGeometry(
size = [[menuItem title] sizeWithAttributes:
TkMacOSXNSFontAttributesForFont(tkfont)];
}
- size.width += menuTextLeadingEdgeMargin +
- menuTextTrailingEdgeMargin;
- if (size.height < fmPtr->linespace) {
- size.height = fmPtr->linespace;
- }
+ size.width += menuTextLeadingEdgeMargin + menuTextTrailingEdgeMargin;
+ size.height -= 1; /* tweak */
if (haveImage && (mePtr->compound != COMPOUND_NONE)) {
int margin = width + menuIconTrailingEdgeMargin;
@@ -1217,9 +1333,11 @@ TkpComputeStandardMenuGeometry(
height = size.height;
}
}
+ else {
+ /* image only. */
+ }
labelWidth = width + menuItemExtraWidth;
mePtr->height = height + menuItemExtraHeight;
-
if (mePtr->type == CASCADE_ENTRY) {
modifierWidth = modifierCharWidth;
} else if (mePtr->accelLength == 0) {
@@ -1250,30 +1368,18 @@ TkpComputeStandardMenuGeometry(
if (entryWidth > maxWidth) {
maxWidth = entryWidth;
}
+ menuPtr->entries[i]->width = entryWidth;
mePtr->height += 2 * activeBorderWidth;
}
+ mePtr->x = x;
mePtr->y = y;
y += menuPtr->entries[i]->height + borderWidth;
- if (y > windowHeight) {
- windowHeight = y;
- }
}
-
- for (j = lastColumnBreak; j < menuPtr->numEntries; j++) {
- columnEntryPtr = menuPtr->entries[j];
- columnEntryPtr->indicatorSpace = maxIndicatorSpace;
- columnEntryPtr->width = maxIndicatorSpace + maxWidth
- + 2 * activeBorderWidth;
- columnEntryPtr->x = x;
- columnEntryPtr->entryFlags |= ENTRY_LAST_COLUMN;
- }
- windowWidth = x + maxIndicatorSpace + maxWidth
- + 2 * activeBorderWidth + borderWidth;
- windowHeight += borderWidth;
-
+ windowWidth = menuSize.width;
if (windowWidth <= 0) {
windowWidth = 1;
}
+ windowHeight = menuSize.height;
if (windowHeight <= 0) {
windowHeight = 1;
}
@@ -1481,10 +1587,10 @@ TkpMenuInit(void)
#undef observe
[NSMenuItem setUsesUserKeyEquivalents:NO];
- tkColPtr = TkpGetColor(None, DEF_MENU_BG_COLOR);
+ tkColPtr = TkpGetColor(NULL, DEF_MENU_BG_COLOR);
defaultBg = tkColPtr->color.pixel;
ckfree(tkColPtr);
- tkColPtr = TkpGetColor(None, DEF_MENU_FG);
+ tkColPtr = TkpGetColor(NULL, DEF_MENU_FG);
defaultFg = tkColPtr->color.pixel;
ckfree(tkColPtr);
diff --git a/macosx/tkMacOSXMenubutton.c b/macosx/tkMacOSXMenubutton.c
index 1acefe5..b2b4b76 100644
--- a/macosx/tkMacOSXMenubutton.c
+++ b/macosx/tkMacOSXMenubutton.c
@@ -47,17 +47,23 @@ typedef struct MacMenuButton {
} MacMenuButton;
/*
- * Forward declarations for procedures defined later in this file:
+ * Forward declarations for static functions defined later in this file:
*/
static void MenuButtonEventProc(ClientData clientData, XEvent *eventPtr);
-static void MenuButtonBackgroundDrawCB ( MacMenuButton *ptr, SInt16 depth, Boolean isColorDev);
-static void MenuButtonContentDrawCB ( ThemeButtonKind kind, const HIThemeButtonDrawInfo * info, MacMenuButton *ptr, SInt16 depth, Boolean isColorDev);
+static void MenuButtonBackgroundDrawCB (MacMenuButton *ptr, SInt16 depth,
+ Boolean isColorDev);
+static void MenuButtonContentDrawCB (ThemeButtonKind kind,
+ const HIThemeButtonDrawInfo * info,
+ MacMenuButton *ptr, SInt16 depth,
+ Boolean isColorDev);
static void MenuButtonEventProc ( ClientData clientData, XEvent *eventPtr);
-static void TkMacOSXComputeMenuButtonParams (TkMenuButton * butPtr, ThemeButtonKind* btnkind, HIThemeButtonDrawInfo* drawinfo);
-static int TkMacOSXComputeMenuButtonDrawParams (TkMenuButton * butPtr, DrawParams * dpPtr);
-static void TkMacOSXDrawMenuButton (MacMenuButton *butPtr,
- GC gc, Pixmap pixmap);
+static void TkMacOSXComputeMenuButtonParams (TkMenuButton * butPtr,
+ ThemeButtonKind* btnkind,
+ HIThemeButtonDrawInfo* drawinfo);
+static void TkMacOSXComputeMenuButtonDrawParams (TkMenuButton * butPtr,
+ DrawParams * dpPtr);
+static void TkMacOSXDrawMenuButton (MacMenuButton *butPtr, GC gc, Pixmap pixmap);
static void DrawMenuButtonImageAndText(TkMenuButton* butPtr);
/*
@@ -70,11 +76,45 @@ Tk_ClassProcs tkpMenubuttonClass = {
TkMenuButtonWorldChanged, /* worldChangedProc */
};
+/*
+ * We use Apple's Pop-Up Button widget to represent the Tk Menubutton.
+ * However, we do not use the NSPopUpButton class for this control. Instead we
+ * render the Pop-Up Button using the HITheme library. This imposes some
+ * constraints on what can be done. The HITheme renderer allows only specific
+ * dimensions for the button.
+ *
+ * The HITheme library allows drawing a Pop-Up Button with an arbitrary bounds
+ * rectangle. However the button is always drawn as a rounded box which is 22
+ * pixels high. If the bounds rectangle is less than 22 pixels high, the
+ * button is drawn at the top of the rectangle and the bottom of the button is
+ * clipped away. So we set a minimum height of 22 pixels for a Menubutton. If
+ * the bounds rectangle is more than 22 pixels high, then the button is drawn
+ * centered vertically in the bounds rectangle.
+ *
+ * The content rectangle of the button is inset by 14 pixels on the left and 28
+ * pixels on the right. The rightmost part of the button contains the blue
+ * double-arrow symbol which is 28 pixels wide.
+ *
+ * To maintain compatibility with code that runs on multiple operating systems,
+ * the width and height of the content rectangle includes the borderWidth, the
+ * highlightWidth and the padX and padY dimensions of the Menubutton. However,
+ * to be consistent with the standard Apple appearance, the content is always
+ * be drawn at the left side of the content rectangle. All of the excess space
+ * appears on the right side of the content, and the anchor property is
+ * ignored. The easiest way to comply with Apple's Human Interface Guidelines
+ * would be to set bd = highlightthickness = padx = 0 and to specify an
+ * explicit width for the button. Apple also recommends using the same width
+ * for all Pop-Up Buttons in a given window.
+ */
+
+#define LEFT_INSET 8
+#define RIGHT_INSET 28
+#define MIN_HEIGHT 22
/*
*----------------------------------------------------------------------
*
- * TkpCreateMenuButton --
+ * TkpCreateMenuButton --
*
* Allocate a new TkMenuButton structure.
*
@@ -93,13 +133,12 @@ TkpCreateMenuButton(
{
MacMenuButton *mbPtr = (MacMenuButton *) ckalloc(sizeof(MacMenuButton));
- Tk_CreateEventHandler(tkwin, ActivateMask,
- MenuButtonEventProc, (ClientData) mbPtr);
+ Tk_CreateEventHandler(tkwin, ActivateMask, MenuButtonEventProc,
+ (ClientData) mbPtr);
mbPtr->flags = FIRST_DRAW;
mbPtr->btnkind = kThemePopupButton;
bzero(&mbPtr->drawinfo, sizeof(mbPtr->drawinfo));
bzero(&mbPtr->lastdrawinfo, sizeof(mbPtr->lastdrawinfo));
-
return (TkMenuButton *) mbPtr;
}
@@ -165,12 +204,13 @@ TkpDisplayMenuButton(
* TkpDestroyMenuButton --
*
* Free data structures associated with the menubutton control.
+ * This is a no-op on the Mac.
*
* Results:
* None.
*
* Side effects:
- * Restores the default control state.
+ * None.
*
*----------------------------------------------------------------------
*/
@@ -204,15 +244,12 @@ TkpComputeMenuButtonGeometry(butPtr)
register TkMenuButton *butPtr; /* Widget record for menu button. */
{
int width, height, avgWidth, haveImage = 0, haveText = 0;
- MacMenuButton *mbPtr = (MacMenuButton*)butPtr;
int txtWidth, txtHeight;
Tk_FontMetrics fm;
- DrawParams drawParams;
- int paddingx = 0;
- int paddingy = 0;
+ int highlightWidth = butPtr->highlightWidth > 0 ? butPtr->highlightWidth : 0;
/*
- * First figure out the size of the contents of the button.
+ * First compute the size of the contents of the button.
*/
width = 0;
@@ -221,8 +258,6 @@ TkpComputeMenuButtonGeometry(butPtr)
txtHeight = 0;
avgWidth = 0;
- TkMacOSXComputeMenuButtonParams(butPtr, &mbPtr->btnkind, &mbPtr->drawinfo);
-
if (butPtr->image != NULL) {
Tk_SizeOfImage(butPtr->image, &width, &height);
haveImage = 1;
@@ -231,17 +266,16 @@ TkpComputeMenuButtonGeometry(butPtr)
haveImage = 1;
}
- if (haveImage == 0 || butPtr->compound != COMPOUND_NONE) {
+ if (butPtr->text && strlen(butPtr->text) > 0) {
+ haveText = 1;
Tk_FreeTextLayout(butPtr->textLayout);
butPtr->textLayout = Tk_ComputeTextLayout(butPtr->tkfont,
butPtr->text, -1, butPtr->wrapLength,
butPtr->justify, 0, &butPtr->textWidth, &butPtr->textHeight);
-
txtWidth = butPtr->textWidth;
txtHeight = butPtr->textHeight;
avgWidth = Tk_TextWidth(butPtr->tkfont, "0", 1);
Tk_GetFontMetrics(butPtr->tkfont, &fm);
- haveText = (txtWidth != 0 && txtHeight != 0);
}
/*
@@ -251,7 +285,7 @@ TkpComputeMenuButtonGeometry(butPtr)
* image, because otherwise it is not really a compound button.
*/
- if (butPtr->compound != COMPOUND_NONE && haveImage && haveText) {
+ if (haveImage && haveText) {
switch ((enum compound) butPtr->compound) {
case COMPOUND_TOP:
case COMPOUND_BOTTOM: {
@@ -293,76 +327,29 @@ TkpComputeMenuButtonGeometry(butPtr)
}
} else {
- if (haveImage) {
+ if (haveImage) { /* Image only */
if (butPtr->width > 0) {
width = butPtr->width;
}
if (butPtr->height > 0) {
height = butPtr->height;
}
- } else {
+ } else { /* Text only */
width = txtWidth;
height = txtHeight;
if (butPtr->width > 0) {
- width = butPtr->width * avgWidth;
+ width = butPtr->width * avgWidth + 2*butPtr->padX;
}
if (butPtr->height > 0) {
- height = butPtr->height * fm.linespace;
+ height = butPtr->height * fm.linespace + 2*butPtr->padY;
}
}
}
- width += 2 * butPtr->padX - 2;
- height += 2 * butPtr->padY - 2;
-
- /*Add padding for button arrows.*/
- width += 22;
-
- /*
- * Now figure out the size of the border decorations for the button.
- */
-
- if (butPtr->highlightWidth < 0) {
- butPtr->highlightWidth = 0;
- }
- butPtr->inset = 0;
- butPtr->inset += butPtr->highlightWidth;
-
- TkMacOSXComputeMenuButtonDrawParams(butPtr,&drawParams);
-
- HIRect tmpRect;
- HIRect contBounds;
-
- tmpRect = CGRectMake(0, 0, width, height);
-
- HIThemeGetButtonContentBounds(&tmpRect, &mbPtr->drawinfo, &contBounds);
-
-
-
- /* If the content region has a minimum height, match it. */
- if (height < contBounds.size.height) {
- height = contBounds.size.height;
- }
-
- /* If the content region has a minimum width, match it. */
- if (width < contBounds.size.width) {
- width = contBounds.size.width;
- }
-
- /* Pad to fill difference between content bounds and button bounds. */
- paddingx = tmpRect.origin.x - contBounds.origin.x;
- paddingy = tmpRect.origin.y - contBounds.origin.y;
-
- if (paddingx > 0) {
- width += paddingx;
- }
- if (paddingy > 0) {
- height += paddingy;
- }
-
- width += butPtr->inset*2;
- height += butPtr->inset*2;
-
-
+
+ butPtr->inset = highlightWidth + butPtr->borderWidth;
+ width += LEFT_INSET + RIGHT_INSET + 2*butPtr->inset;
+ height += 2*butPtr->inset;
+ height = height < MIN_HEIGHT ? MIN_HEIGHT : height;
Tk_GeometryRequest(butPtr->tkwin, width, height);
Tk_SetInternalBorder(butPtr->tkwin, butPtr->inset);
}
@@ -427,8 +414,8 @@ DrawMenuButtonImageAndText(
pressed = 1;
}
- haveText = (butPtr->textWidth != 0 && butPtr->textHeight != 0);
- if (butPtr->compound != COMPOUND_NONE && haveImage && haveText) {
+ haveText = (butPtr->textWidth != 0 && butPtr->textHeight != 0);
+ if (butPtr->compound != COMPOUND_NONE && haveImage && haveText) {
int x = 0;
int y = 0;
textXOffset = 0;
@@ -446,8 +433,8 @@ DrawMenuButtonImageAndText(
imageYOffset = butPtr->textHeight + butPtr->padY;
}
fullHeight = height + butPtr->textHeight + butPtr->padY;
- fullWidth = (width > butPtr->textWidth ? width :
- butPtr->textWidth);
+ fullWidth = (width > butPtr->textWidth ?
+ width : butPtr->textWidth);
textXOffset = (fullWidth - butPtr->textWidth)/2;
imageXOffset = (fullWidth - width)/2;
break;
@@ -489,10 +476,10 @@ DrawMenuButtonImageAndText(
}
TkComputeAnchor(butPtr->anchor, tkwin,
- butPtr->padX + butPtr->borderWidth,
- butPtr->padY + butPtr->borderWidth,
+ butPtr->padX + butPtr->inset,
+ butPtr->padY + butPtr->inset,
fullWidth, fullHeight, &x, &y);
- imageXOffset += x;
+ imageXOffset = LEFT_INSET;
imageYOffset += y;
textYOffset -= 1;
@@ -517,36 +504,32 @@ DrawMenuButtonImageAndText(
butPtr->underline);
} else {
if (haveImage) {
- int x = 0;
- int y;
+ int x, y;
TkComputeAnchor(butPtr->anchor, tkwin,
butPtr->padX + butPtr->borderWidth,
butPtr->padY + butPtr->borderWidth,
width, height, &x, &y);
- imageXOffset += x;
- imageYOffset += y;
-
- if (butPtr->image != NULL) {
- Tk_RedrawImage(butPtr->image, 0, 0, width, height,
- pixmap, imageXOffset, imageYOffset);
+ imageXOffset = LEFT_INSET;
+ imageYOffset += y;
+ if (butPtr->image != NULL) {
+ Tk_RedrawImage(butPtr->image, 0, 0, width, height,
+ pixmap, imageXOffset, imageYOffset);
} else {
XSetClipOrigin(butPtr->display, dpPtr->gc, x, y);
XCopyPlane(butPtr->display, butPtr->bitmap,
- pixmap, dpPtr->gc,
- 0, 0, (unsigned int) width,
- (unsigned int) height,
- imageXOffset, imageYOffset, 1);
+ pixmap, dpPtr->gc,
+ 0, 0, (unsigned int) width,
+ (unsigned int) height,
+ imageXOffset, imageYOffset, 1);
XSetClipOrigin(butPtr->display, dpPtr->gc, 0, 0);
}
} else {
- /*Move x back by eight pixels to give the menubutton arrows room.*/
- int x = 0;
- int y;
- textXOffset = 8;
+ int x, y;
+ textXOffset = LEFT_INSET;
TkComputeAnchor(butPtr->anchor, tkwin, butPtr->padX, butPtr->padY,
butPtr->textWidth, butPtr->textHeight, &x, &y);
Tk_DrawTextLayout(butPtr->display, pixmap, dpPtr->gc,
- butPtr->textLayout, x - textXOffset, y, 0, -1);
+ butPtr->textLayout, textXOffset, y, 0, -1);
y += butPtr->textHeight/2;
}
}
@@ -578,7 +561,6 @@ TkMacOSXDrawMenuButton(
* the bevel button */
Pixmap pixmap) /* The pixmap we are drawing into - needed
* for the bevel button */
-
{
TkMenuButton * butPtr = ( TkMenuButton *)mbPtr;
TkWindow * winPtr;
@@ -591,10 +573,9 @@ TkMacOSXDrawMenuButton(
TkMacOSXComputeMenuButtonParams(butPtr, &mbPtr->btnkind, &mbPtr->drawinfo);
- cntrRect = CGRectMake(winPtr->privatePtr->xOff, winPtr->privatePtr->yOff, Tk_Width(butPtr->tkwin),Tk_Height(butPtr->tkwin));
-
- cntrRect = CGRectInset(cntrRect, butPtr->inset, butPtr->inset);
-
+ cntrRect = CGRectMake(winPtr->privatePtr->xOff, winPtr->privatePtr->yOff,
+ Tk_Width(butPtr->tkwin),
+ Tk_Height(butPtr->tkwin));
if (useNewerHITools == 1) {
HIRect contHIRec;
@@ -617,17 +598,15 @@ TkMacOSXDrawMenuButton(
hiinfo.animation.time.start = hiinfo.animation.time.current;
}
- HIThemeDrawButton(&cntrRect, &hiinfo, dc.context, kHIThemeOrientationNormal, &contHIRec);
-
+ HIThemeDrawButton(&cntrRect, &hiinfo, dc.context,
+ kHIThemeOrientationNormal, &contHIRec);
TkMacOSXRestoreDrawingContext(&dc);
-
- MenuButtonContentDrawCB( mbPtr->btnkind, &mbPtr->drawinfo, (MacMenuButton *)mbPtr, 32, true);
+ MenuButtonContentDrawCB( mbPtr->btnkind, &mbPtr->drawinfo,
+ (MacMenuButton *)mbPtr, 32, true);
} else {
if (!TkMacOSXSetupDrawingContext(pixmap, dpPtr->gc, 1, &dc)) {
return;
}
-
-
TkMacOSXRestoreDrawingContext(&dc);
}
mbPtr->lastdrawinfo = mbPtr->drawinfo;
@@ -696,8 +675,7 @@ MenuButtonContentDrawCB (
if (tkwin == NULL || !Tk_IsMapped(tkwin)) {
return;
}
-
- DrawMenuButtonImageAndText( butPtr);
+ DrawMenuButtonImageAndText(butPtr);
}
/*
@@ -761,19 +739,18 @@ MenuButtonEventProc(
*/
static void
-TkMacOSXComputeMenuButtonParams(TkMenuButton * butPtr, ThemeButtonKind* btnkind, HIThemeButtonDrawInfo *drawinfo)
+TkMacOSXComputeMenuButtonParams(
+ TkMenuButton * butPtr,
+ ThemeButtonKind* btnkind,
+ HIThemeButtonDrawInfo *drawinfo)
{
MacMenuButton *mbPtr = (MacMenuButton *)butPtr;
- if (butPtr->image || butPtr->bitmap) {
+ if (butPtr->image || butPtr->bitmap || butPtr->text) {
/* TODO: allow for Small and Mini menubuttons. */
*btnkind = kThemePopupButton;
- } else {
- if (!butPtr->text || !*butPtr->text) {
- *btnkind = kThemeArrowButton;
- } else {
- *btnkind = kThemePopupButton;
- }
+ } else { /* This should never happen. */
+ *btnkind = kThemeArrowButton;
}
drawinfo->value = kThemeButtonOff;
@@ -812,24 +789,25 @@ TkMacOSXComputeMenuButtonParams(TkMenuButton * butPtr, ThemeButtonKind* btnkind,
*
* TkMacOSXComputeMenuButtonDrawParams --
*
- * This procedure computes the various parameters used
- * when drawing a button
- * These are determined by the various tk button parameters
+ * This procedure selects an appropriate drawing context for
+ * drawing a menubutton.
*
* Results:
- * 1 if control will be used, 0 otherwise.
+ * None.
*
* Side effects:
- * Sets the button draw parameters
+ * Sets the button draw parameters.
*
*----------------------------------------------------------------------
*/
-static int
-TkMacOSXComputeMenuButtonDrawParams(TkMenuButton * butPtr, DrawParams * dpPtr)
+static void
+TkMacOSXComputeMenuButtonDrawParams(
+ TkMenuButton * butPtr,
+ DrawParams * dpPtr)
{
- dpPtr->hasImageOrBitmap = ((butPtr->image != NULL)
- || (butPtr->bitmap != None));
+ dpPtr->hasImageOrBitmap = ((butPtr->image != NULL) ||
+ (butPtr->bitmap != None));
dpPtr->border = butPtr->normalBorder;
if ((butPtr->state == STATE_DISABLED) && (butPtr->disabledFg != NULL)) {
dpPtr->gc = butPtr->disabledGC;
@@ -839,8 +817,6 @@ TkMacOSXComputeMenuButtonDrawParams(TkMenuButton * butPtr, DrawParams * dpPtr)
} else {
dpPtr->gc = butPtr->normalTextGC;
}
-
- return 1;
}
/*
diff --git a/macosx/tkMacOSXMouseEvent.c b/macosx/tkMacOSXMouseEvent.c
index 828d874..2d5d152 100644
--- a/macosx/tkMacOSXMouseEvent.c
+++ b/macosx/tkMacOSXMouseEvent.c
@@ -24,6 +24,7 @@ typedef struct {
Point global;
Point local;
} MouseEventData;
+static Tk_Window captureWinPtr = NULL; /* Current capture window; may be NULL. */
static int GenerateButtonEvent(MouseEventData *medPtr);
static unsigned int ButtonModifiers2State(UInt32 buttonState,
@@ -106,23 +107,32 @@ enum {
}
}
- Window window = TkMacOSXGetXWindow(eventWindow);
- Tk_Window tkwin = window ? Tk_IdToWindow(TkGetDisplayList()->display,
- window) : NULL;
- if (!tkwin) {
+ 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;
}
- TkWindow *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);
+ tkwin = Tk_TopCoordsToWindow(tkwin, local.x, local.y, &win_x, &win_y);
unsigned int state = 0;
NSInteger button = [theEvent buttonNumber];
@@ -572,6 +582,56 @@ TkpWarpPointer(
}
/*
+ *----------------------------------------------------------------------
+ *
+ * TkpSetCapture --
+ *
+ * This function captures the mouse so that all future events will be
+ * reported to this window, even if the mouse is outside the window. If
+ * the specified window is NULL, then the mouse is released.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Sets the capture flag and captures the mouse.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TkpSetCapture(
+ TkWindow *winPtr) /* Capture window, or NULL. */
+{
+ while (winPtr && !Tk_IsTopLevel(winPtr)) {
+ winPtr = winPtr->parentPtr;
+ }
+ captureWinPtr = (Tk_Window) winPtr;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkMacOSXGetCapture --
+ *
+ * Results:
+ * Returns the current grab window
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tk_Window
+TkMacOSXGetCapture(void)
+{
+ return captureWinPtr;
+}
+
+
+
+/*
* Local Variables:
* mode: objc
* c-basic-offset: 4
diff --git a/macosx/tkMacOSXNotify.c b/macosx/tkMacOSXNotify.c
index 88e7c76..3a32527 100644
--- a/macosx/tkMacOSXNotify.c
+++ b/macosx/tkMacOSXNotify.c
@@ -84,7 +84,7 @@ InspectQueueRestrictProc(
const char *name;
long serial = ve->serial;
long time = eventPtr->xkey.time;
-
+
if (eventPtr->type == VirtualEvent) {
name = ve->name;
} else {
@@ -137,14 +137,14 @@ void DebugPrintQueue(void)
/*
* Since the contentView is the first responder for a Tk Window, it is
* responsible for sending events up the responder chain. We also check
- * the pasteboard here.
+ * the pasteboard here.
*/
- (void) sendEvent: (NSEvent *) theEvent
{
[super sendEvent:theEvent];
[NSApp tkCheckPasteboard];
#ifdef TK_MAC_DEBUG_EVENTS
- fprintf(stderr, "Sending event of type %d\n", (int)[theEvent type]);
+ fprintf(stderr, "Sending event of type %d\n", (int)[theEvent type]);
DebugPrintQueue();
#endif
}
diff --git a/macosx/tkMacOSXPrivate.h b/macosx/tkMacOSXPrivate.h
index 27fe6d8..105317d 100644
--- a/macosx/tkMacOSXPrivate.h
+++ b/macosx/tkMacOSXPrivate.h
@@ -342,7 +342,7 @@ VISIBILITY_HIDDEN
@interface TKContentView(TKWindowEvent)
- (void) drawRect: (NSRect) rect;
-- (void) generateExposeEvents: (HIShapeRef) shape;
+- (void) generateExposeEvents: (HIShapeRef) shape;
- (void) tkToolbarButton: (id) sender;
- (BOOL) isOpaque;
- (BOOL) wantsDefaultClipping;
diff --git a/macosx/tkMacOSXScrlbr.c b/macosx/tkMacOSXScrlbr.c
index d1287bb..4a108db 100644
--- a/macosx/tkMacOSXScrlbr.c
+++ b/macosx/tkMacOSXScrlbr.c
@@ -48,7 +48,7 @@ typedef struct MacScrollbar {
TkScrollbar information; /* Generic scrollbar info. */
GC troughGC; /* For drawing trough. */
GC copyGC; /* Used for copying from pixmap onto screen. */
- Bool buttonDown; /* Is the mouse button down? */
+ Bool buttonDown; /* Is the mouse button down? */
Bool mouseOver; /* Is the pointer over the scrollbar. */
HIThemeTrackDrawInfo info; /* Controls how the scrollbar is drawn. */
} MacScrollbar;
@@ -119,11 +119,11 @@ TkpCreateScrollbar(
MacScrollbar *scrollPtr = (MacScrollbar *)ckalloc(sizeof(MacScrollbar));
- scrollPtr->troughGC = None;
- scrollPtr->copyGC = None;
+ scrollPtr->troughGC = NULL;
+ scrollPtr->copyGC = NULL;
scrollPtr->info = defaultInfo;
scrollPtr->buttonDown = false;
-
+
Tk_CreateEventHandler(tkwin,
ExposureMask |
StructureNotifyMask |
@@ -561,7 +561,7 @@ static int
ScrollbarEvent(TkScrollbar *scrollPtr, XEvent *eventPtr)
{
MacScrollbar *msPtr = (MacScrollbar *)scrollPtr;
-
+
/* The pressState does not indicate whether the moused button was
* pressed at some location in the Scrollbar. Rather, it indicates
* that the scrollbar should appear as if it were pressed in that
diff --git a/macosx/tkMacOSXSend.c b/macosx/tkMacOSXSend.c
index 3b24a56..1fdf048 100644
--- a/macosx/tkMacOSXSend.c
+++ b/macosx/tkMacOSXSend.c
@@ -325,7 +325,7 @@ Tk_SendObjCmd(
int objc, /* Number of arguments */
Tcl_Obj *const objv[]) /* The arguments */
{
- const char *const sendOptions[] = {"-async", "-displayof", "-", NULL};
+ const char *const sendOptions[] = {"-async", "-displayof", "--", NULL};
char *stringRep, *destName;
/*int async = 0;*/
int i, index, firstArg;
diff --git a/macosx/tkMacOSXSubwindows.c b/macosx/tkMacOSXSubwindows.c
index 0f9214f..805d58f 100644
--- a/macosx/tkMacOSXSubwindows.c
+++ b/macosx/tkMacOSXSubwindows.c
@@ -149,6 +149,7 @@ XMapWindow(
if (Tk_IsTopLevel(macWin->winPtr)) {
if (!Tk_IsEmbedded(macWin->winPtr)) {
NSWindow *win = TkMacOSXDrawableWindow(window);
+
/*
* We want to activate Tk when a toplevel is mapped
* but we must not supply YES here. This is because
@@ -157,16 +158,32 @@ XMapWindow(
* the app to activate too early can make the menu bar
* unresponsive.
*/
+
+ TkMacOSXApplyWindowAttributes(macWin->winPtr, win);
+ [win setExcludedFromWindowsMenu:NO];
[NSApp activateIgnoringOtherApps:NO];
+ [[win contentView] setNeedsDisplay:YES];
if ( [win canBecomeKeyWindow] ) {
[win makeKeyAndOrderFront:NSApp];
+ } else {
+ [win orderFrontRegardless];
}
- TkMacOSXApplyWindowAttributes(macWin->winPtr, win);
+
+ /*
+ * In some cases the toplevel will not be drawn unless we process
+ * all pending events now. See ticket 56a1823c73.
+ */
+
+ [NSApp _lockAutoreleasePool];
+ while (Tcl_DoOneEvent(TCL_WINDOW_EVENTS| TCL_DONT_WAIT)) {}
+ [NSApp _unlockAutoreleasePool];
} else {
+
/*
* Rebuild the container's clipping region and display
* the window.
*/
+
TkWindow *contWinPtr = TkpGetOtherWindow(macWin->winPtr);
TkMacOSXInvalClipRgns((Tk_Window)contWinPtr);
TkMacOSXInvalidateWindow(macWin, TK_PARENT_WINDOW);
@@ -186,7 +203,9 @@ XMapWindow(
event.xmap.event = window;
event.xmap.override_redirect = macWin->winPtr->atts.override_redirect;
Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL);
+
} else {
+
/*
* Rebuild the parent's clipping region and display the window.
*
@@ -207,11 +226,10 @@ XMapWindow(
NotifyVisibility(macWin->winPtr, &event);
/*
- * Make sure that subwindows get displayed.
+ * This seems to be needed to ensure that all subwindows get displayed.
*/
GenerateConfigureNotify(macWin->winPtr, 1);
-
}
/*
@@ -280,11 +298,7 @@ XUnmapWindow(
if (!Tk_IsEmbedded(winPtr) &&
winPtr->wmInfoPtr->hints.initial_state!=IconicState) {
NSWindow *win = TkMacOSXDrawableWindow(window);
-
- if ([win isVisible]) {
- [[win parentWindow] removeChildWindow:win];
- [win orderOut:NSApp];
- }
+ [win orderOut:nil];
}
TkMacOSXInvalClipRgns((Tk_Window) winPtr);
@@ -1310,7 +1324,7 @@ TkMacOSXWinCGBounds(
* UpdateOffsets --
*
* Updates the X & Y offsets of the given TkWindow from the TopLevel it is
- * a decendant of.
+ * a descendant of.
*
* Results:
* None.
diff --git a/macosx/tkMacOSXWindowEvent.c b/macosx/tkMacOSXWindowEvent.c
index ad6af30..212381e 100644
--- a/macosx/tkMacOSXWindowEvent.c
+++ b/macosx/tkMacOSXWindowEvent.c
@@ -75,12 +75,10 @@ extern NSString *NSWindowDidOrderOffScreenNotification;
if (winPtr) {
WmInfo *wmPtr = winPtr->wmInfoPtr;
NSRect bounds = [w frame];
- NSRect screenRect = [[w screen] frame];
int x, y, width = -1, height = -1, flags = 0;
- int minY = 1 + [[NSApp mainMenu] menuBarHeight];
x = bounds.origin.x;
- y = screenRect.size.height - (bounds.origin.y + bounds.size.height);
+ y = tkMacOSXZeroScreenHeight - (bounds.origin.y + bounds.size.height);
if (winPtr->changes.x != x || winPtr->changes.y != y) {
flags |= TK_LOCATION_CHANGED;
} else {
@@ -101,20 +99,6 @@ extern NSString *NSWindowDidOrderOffScreenNotification;
flags |= TK_MACOSX_HANDLE_EVENT_IMMEDIATELY;
}
- /*
- * Mac windows cannot go higher than the bottom of the menu bar. The
- * Tk window manager can request that a window be drawn so that it
- * overlaps the menu bar, but it will actually be drawn immediately
- * below the menu bar. In such a case it saves a lot of trouble and
- * causes no harm if we let Tk think that the window is located at the
- * requested point. (Many of the the tests assume that this is the
- * case, especially for windows with upper left corner at (0,0).) So
- * we just tell a harmless white lie here.
- */
-
- if (y == minY && wmPtr->y < minY) {
- y = wmPtr->y;
- }
TkGenWMConfigureEvent((Tk_Window) winPtr, x, y, width, height, flags);
}
@@ -523,7 +507,9 @@ GenerateActivateEvents(
int activeFlag)
{
TkGenerateActivateEvents(winPtr, activeFlag);
- TkMacOSXGenerateFocusEvent(winPtr, activeFlag);
+ if (activeFlag || ![NSApp isActive]) {
+ TkMacOSXGenerateFocusEvent(winPtr, activeFlag);
+ }
return true;
}
@@ -680,7 +666,6 @@ TkGenWMConfigureEvent(
if (flags & TK_LOCATION_CHANGED) {
wmPtr->x = x;
wmPtr->y = y;
- //wmPtr->flags &= ~(WM_NEGATIVE_X | WM_NEGATIVE_Y);
}
if ((flags & TK_SIZE_CHANGED) && !(wmPtr->flags & WM_SYNC_PENDING) &&
((width != Tk_Width(tkwin)) || (height != Tk_Height(tkwin)))) {
diff --git a/macosx/tkMacOSXWm.c b/macosx/tkMacOSXWm.c
index d76f18c..a607ae5 100644
--- a/macosx/tkMacOSXWm.c
+++ b/macosx/tkMacOSXWm.c
@@ -152,13 +152,13 @@ static const struct {
typedef enum {
WMATT_ALPHA, WMATT_FULLSCREEN, WMATT_MODIFIED, WMATT_NOTIFY,
WMATT_TITLEPATH, WMATT_TOPMOST, WMATT_TRANSPARENT,
- _WMATT_LAST_ATTRIBUTE
+ WMATT_TYPE, _WMATT_LAST_ATTRIBUTE
} WmAttribute;
static const char *const WmAttributeNames[] = {
"-alpha", "-fullscreen", "-modified", "-notify",
"-titlepath", "-topmost", "-transparent",
- NULL
+ "-type", NULL
};
/*
@@ -322,6 +322,7 @@ static void GetMaxSize(TkWindow *winPtr, int *maxWidthPtr,
int *maxHeightPtr);
static void RemapWindows(TkWindow *winPtr,
MacDrawable *parentWin);
+static void RemoveTransient(TkWindow *winPtr);
#pragma mark NSWindow(TKWm)
@@ -594,7 +595,8 @@ SetWindowSizeLimits(
*
* FrontWindowAtPoint --
*
- * Find frontmost toplevel window at a given screen location.
+ * Find frontmost toplevel window at a given screen location which has the
+ * specified mainPtr. If the location is in the title bar, return NULL.
*
* Results:
* TkWindow*.
@@ -607,7 +609,8 @@ SetWindowSizeLimits(
static TkWindow*
FrontWindowAtPoint(
- int x, int y)
+ int x,
+ int y)
{
NSPoint p = NSMakePoint(x, tkMacOSXZeroScreenHeight - y);
NSArray *windows = [NSApp orderedWindows];
@@ -615,11 +618,28 @@ FrontWindowAtPoint(
for (NSWindow *w in windows) {
winPtr = TkMacOSXGetTkWindow(w);
- if (winPtr && NSMouseInRect(p, [w frame], NO)) {
- break;
+ if (winPtr) {
+ WmInfo *wmPtr = winPtr->wmInfoPtr;
+ NSRect windowFrame = [w frame];
+ NSRect contentFrame = [w frame];
+ contentFrame.size.height = [[w contentView] frame].size.height;
+ /*
+ * For consistency with other platforms, points in the
+ * title bar are not considered to be contained in the
+ * window.
+ */
+
+ if ((wmPtr->hints.initial_state == NormalState ||
+ wmPtr->hints.initial_state == ZoomState)) {
+ if (NSMouseInRect(p, contentFrame, NO)) {
+ return winPtr;
+ } else if (NSMouseInRect(p, windowFrame, NO)) {
+ return NULL;
+ }
+ }
}
}
- return winPtr;
+ return NULL;
}
/*
@@ -649,7 +669,7 @@ TkWmNewWindow(
wmPtr->reparent = None;
wmPtr->titleUid = NULL;
wmPtr->iconName = NULL;
- wmPtr->master = None;
+ wmPtr->master = NULL;
wmPtr->hints.flags = InputHint | StateHint;
wmPtr->hints.input = True;
wmPtr->hints.initial_state = NormalState;
@@ -659,9 +679,9 @@ TkWmNewWindow(
wmPtr->hints.icon_mask = None;
wmPtr->hints.window_group = None;
wmPtr->leaderName = NULL;
- wmPtr->masterWindowName = NULL;
wmPtr->icon = NULL;
wmPtr->iconFor = NULL;
+ wmPtr->transientPtr = NULL;
wmPtr->sizeHintsFlags = 0;
wmPtr->minWidth = wmPtr->minHeight = 1;
wmPtr->maxWidth = 0;
@@ -814,10 +834,6 @@ TkWmMapWindow(
*/
XMapWindow(winPtr->display, winPtr->window);
-
- /*Add window to Window menu.*/
- NSWindow *win = TkMacOSXDrawableWindow(winPtr->window);
- [win setExcludedFromWindowsMenu:NO];
}
/*
@@ -871,6 +887,12 @@ TkWmDeadWindow(
if (wmPtr == NULL) {
return;
}
+
+ /*
+ *If the dead window is a transient, remove it from the master's list.
+ */
+
+ RemoveTransient(winPtr);
Tk_ManageGeometry((Tk_Window) winPtr, NULL, NULL);
Tk_DeleteEventHandler((Tk_Window) winPtr, StructureNotifyMask,
TopLevelEventProc, winPtr);
@@ -886,9 +908,6 @@ TkWmDeadWindow(
if (wmPtr->leaderName != NULL) {
ckfree(wmPtr->leaderName);
}
- if (wmPtr->masterWindowName != NULL) {
- ckfree(wmPtr->masterWindowName);
- }
if (wmPtr->icon != NULL) {
wmPtr2 = ((TkWindow *) wmPtr->icon)->wmInfoPtr;
wmPtr2->iconFor = NULL;
@@ -900,7 +919,6 @@ TkWmDeadWindow(
}
while (wmPtr->protPtr != NULL) {
ProtocolHandler *protPtr = wmPtr->protPtr;
-
wmPtr->protPtr = protPtr->nextPtr;
Tcl_EventuallyFree(protPtr, TCL_DYNAMIC);
}
@@ -915,6 +933,27 @@ TkWmDeadWindow(
}
/*
+ * If the dead window has a transient, remove references to it from
+ * the transient.
+ */
+
+ for (Transient *transientPtr = wmPtr->transientPtr;
+ transientPtr != NULL; transientPtr = transientPtr->nextPtr) {
+ TkWindow *winPtr2 = transientPtr->winPtr;
+ TkWindow *masterPtr = (TkWindow *)TkGetTransientMaster(winPtr2);
+ if (masterPtr == winPtr) {
+ wmPtr2 = winPtr2->wmInfoPtr;
+ wmPtr2->master = NULL;
+ }
+ }
+
+ while (wmPtr->transientPtr != NULL) {
+ Transient *transientPtr = wmPtr->transientPtr;
+ wmPtr->transientPtr = transientPtr->nextPtr;
+ ckfree(transientPtr);
+ }
+
+ /*
* Delete the Mac window and remove it from the windowTable. The window
* could be nil if the window was never mapped. However, we don't do this
* for embedded windows, they don't go in the window list, and they do not
@@ -1301,7 +1340,7 @@ WmSetAttribute(
#if !(MAC_OS_X_VERSION_MAX_ALLOWED < 1070)
[macWindow toggleFullScreen:macWindow];
#else
- TKLog(@"The fullscreen attribute is ignored on this system..");
+ TKLog(@"The fullscreen attribute is ignored on this system.");
#endif
}
break;
@@ -1379,6 +1418,9 @@ WmSetAttribute(
TK_PARENT_WINDOW);
}
break;
+ case WMATT_TYPE:
+ TKLog(@"The type attribute is ignored on macOS.");
+ break;
case _WMATT_LAST_ATTRIBUTE:
default:
return TCL_ERROR;
@@ -1429,6 +1471,9 @@ WmGetAttribute(
case WMATT_TRANSPARENT:
result = Tcl_NewBooleanObj(wmPtr->flags & WM_TRANSPARENT);
break;
+ case WMATT_TYPE:
+ result = Tcl_NewStringObj("unsupported", -1);
+ break;
case _WMATT_LAST_ATTRIBUTE:
default:
break;
@@ -1765,6 +1810,26 @@ WmDeiconifyCmd(
if (wmPtr->icon) {
Tk_UnmapWindow((Tk_Window)wmPtr->icon);
}
+
+ /*
+ * If this window has a transient, the transient must also be deiconified if
+ * it was withdrawn by the master.
+ */
+
+ for (Transient *transientPtr = wmPtr->transientPtr;
+ transientPtr != NULL; transientPtr = transientPtr->nextPtr) {
+ TkWindow *winPtr2 = transientPtr->winPtr;
+ WmInfo *wmPtr2 = winPtr2->wmInfoPtr;
+ TkWindow *masterPtr = (TkWindow *)TkGetTransientMaster(winPtr2);
+ if (masterPtr == winPtr) {
+ if ((wmPtr2->hints.initial_state == WithdrawnState &&
+ (transientPtr->flags & WITHDRAWN_BY_MASTER) != 0)) {
+ TkpWmSetState(winPtr2, NormalState);
+ transientPtr->flags &= ~WITHDRAWN_BY_MASTER;
+ }
+ }
+ }
+
return TCL_OK;
}
@@ -2264,7 +2329,7 @@ WmIconifyCmd(
Tcl_SetErrorCode(interp, "TK", "WM", "ICONIFY", "OVERRIDE_REDIRECT",
NULL);
return TCL_ERROR;
- } else if (wmPtr->master != None) {
+ } else if (wmPtr->master != NULL) {
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"can't iconify \"%s\": it is a transient", winPtr->pathName));
Tcl_SetErrorCode(interp, "TK", "WM", "ICONIFY", "TRANSIENT", NULL);
@@ -2287,6 +2352,23 @@ WmIconifyCmd(
if (wmPtr->icon) {
Tk_MapWindow((Tk_Window)wmPtr->icon);
}
+
+ /*
+ * If this window has a transient the transient must be withdrawn when
+ * the master is iconified.
+ */
+
+ for (Transient *transientPtr = wmPtr->transientPtr;
+ transientPtr != NULL; transientPtr = transientPtr->nextPtr) {
+ TkWindow *winPtr2 = transientPtr->winPtr;
+ TkWindow *masterPtr = (TkWindow *)TkGetTransientMaster(winPtr2);
+ if (masterPtr == winPtr &&
+ winPtr2->wmInfoPtr->hints.initial_state != WithdrawnState) {
+ TkpWmSetState(winPtr2, WithdrawnState);
+ transientPtr->flags |= WITHDRAWN_BY_MASTER;
+ }
+ }
+
return TCL_OK;
}
@@ -2612,7 +2694,7 @@ WmIconwindowCmd(
/*
* The old icon should be withdrawn.
*/
-
+
TkpWmSetState(oldIcon, WithdrawnState);
[win orderOut:nil];
[win setExcludedFromWindowsMenu:YES];
@@ -3371,7 +3453,7 @@ WmStateCmd(
"OVERRIDE_REDIRECT", NULL);
return TCL_ERROR;
}
- if (wmPtr->master != None) {
+ if (wmPtr->master != NULL) {
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"can't iconify \"%s\": it is a transient",
winPtr->pathName));
@@ -3486,32 +3568,29 @@ WmTransientCmd(
{
register WmInfo *wmPtr = winPtr->wmInfoPtr;
Tk_Window master;
+ TkWindow *masterPtr, *w;
WmInfo *wmPtr2;
- char *masterWindowName;
- int length;
+ Transient *transient;
if ((objc != 3) && (objc != 4)) {
Tcl_WrongNumArgs(interp, 2, objv, "window ?master?");
return TCL_ERROR;
}
if (objc == 3) {
- if (wmPtr->master != None) {
+ if (wmPtr->master != NULL) {
Tcl_SetObjResult(interp,
- Tcl_NewStringObj(wmPtr->masterWindowName, -1));
+ Tcl_NewStringObj(Tk_PathName(wmPtr->master), -1));
}
return TCL_OK;
}
if (Tcl_GetString(objv[3])[0] == '\0') {
- wmPtr->master = None;
- if (wmPtr->masterWindowName != NULL) {
- ckfree(wmPtr->masterWindowName);
- }
- wmPtr->masterWindowName = NULL;
+ RemoveTransient(winPtr);
+
} else {
if (TkGetWindowFromObj(interp, tkwin, objv[3], &master) != TCL_OK) {
return TCL_ERROR;
}
- TkWindow* masterPtr = (TkWindow*) master;
+ masterPtr = (TkWindow*) master;
while (!Tk_TopWinHierarchy(masterPtr)) {
/*
@@ -3540,25 +3619,105 @@ WmTransientCmd(
return TCL_ERROR;
}
- if (masterPtr == winPtr) {
- Tcl_SetObjResult(interp, Tcl_ObjPrintf(
- "can't make \"%s\" its own master", Tk_PathName(winPtr)));
- Tcl_SetErrorCode(interp, "TK", "WM", "TRANSIENT", "SELF", NULL);
- return TCL_ERROR;
+ for (w = masterPtr; w != NULL && w->wmInfoPtr != NULL;
+ w = (TkWindow *)w->wmInfoPtr->master) {
+ if (w == winPtr) {
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "setting \"%s\" as master creates a transient/master cycle",
+ Tk_PathName(masterPtr)));
+ Tcl_SetErrorCode(interp, "TK", "WM", "TRANSIENT", "SELF", NULL);
+ return TCL_ERROR;
+ }
}
- wmPtr->master = Tk_WindowId(masterPtr);
- masterWindowName = masterPtr->pathName;
- length = strlen(masterWindowName);
- if (wmPtr->masterWindowName != NULL) {
- ckfree(wmPtr->masterWindowName);
+ /*
+ * Add the transient to the master's list, if it not already there.
+ */
+
+ for (transient = wmPtr2->transientPtr;
+ transient != NULL && transient->winPtr != winPtr;
+ transient = transient->nextPtr) {}
+ if (transient == NULL) {
+ transient = ckalloc(sizeof(Transient));
+ transient->winPtr = winPtr;
+ transient->flags = 0;
+ transient->nextPtr = wmPtr2->transientPtr;
+ wmPtr2->transientPtr = transient;
+ }
+
+ /*
+ * If the master is withdrawn or iconic then withdraw the transient.
+ */
+
+ if ((wmPtr2->hints.initial_state == WithdrawnState ||
+ wmPtr2->hints.initial_state == IconicState) &&
+ wmPtr->hints.initial_state != WithdrawnState){
+ TkpWmSetState(winPtr, WithdrawnState);
+ transient->flags |= WITHDRAWN_BY_MASTER;
}
- wmPtr->masterWindowName = ckalloc(length+1);
- strcpy(wmPtr->masterWindowName, masterWindowName);
+
+ wmPtr->master = (Tk_Window)masterPtr;
}
ApplyMasterOverrideChanges(winPtr, NULL);
return TCL_OK;
}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * RemoveTransient --
+ *
+ * Clears the transient's master record and removes the transient
+ * from the master's list.
+ *
+ * Results:
+ * None
+ *
+ * Side effects:
+ * References to a master are removed from the transient's wmInfo
+ * structure and references to the transient are removed from its
+ * master's wmInfo.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+RemoveTransient(
+ TkWindow *winPtr)
+{
+ WmInfo *wmPtr = winPtr->wmInfoPtr, *wmPtr2;
+ TkWindow *masterPtr;
+ Transient *T, *temp;
+
+ if (wmPtr == NULL || wmPtr->master == NULL) {
+ return;
+ }
+ masterPtr = (TkWindow*)wmPtr->master;
+ wmPtr2 = masterPtr->wmInfoPtr;
+ if (wmPtr2 == NULL) {
+ return;
+ }
+ wmPtr->master = NULL;
+ T = wmPtr2->transientPtr;
+ while (T != NULL) {
+ if (T->winPtr != winPtr) {
+ break;
+ }
+ temp = T->nextPtr;
+ ckfree(T);
+ T = temp;
+ }
+ wmPtr2->transientPtr = T;
+ while (T != NULL) {
+ if (T->nextPtr && T->nextPtr->winPtr == winPtr) {
+ temp = T->nextPtr;
+ T->nextPtr = temp->nextPtr;
+ ckfree(temp);
+ } else {
+ T = T->nextPtr;
+ }
+ }
+}
/*
*----------------------------------------------------------------------
@@ -3599,11 +3758,27 @@ WmWithdrawCmd(
Tcl_SetErrorCode(interp, "TK", "WM", "WITHDRAW", "ICON", NULL);
return TCL_ERROR;
}
+
TkpWmSetState(winPtr, WithdrawnState);
+
NSWindow *win = TkMacOSXDrawableWindow(winPtr->window);
[win orderOut:nil];
[win setExcludedFromWindowsMenu:YES];
+ /*
+ * If this window has a transient, the transient must also be withdrawn.
+ */
+ for (Transient *transientPtr = wmPtr->transientPtr;
+ transientPtr != NULL; transientPtr = transientPtr->nextPtr) {
+ TkWindow *winPtr2 = transientPtr->winPtr;
+ TkWindow *masterPtr = (TkWindow *)TkGetTransientMaster(winPtr2);
+ if (masterPtr == winPtr &&
+ winPtr2->wmInfoPtr->hints.initial_state != WithdrawnState) {
+ TkpWmSetState(winPtr2, WithdrawnState);
+ transientPtr->flags |= WITHDRAWN_BY_MASTER;
+ }
+ }
+
return TCL_OK;
}
@@ -4456,6 +4631,9 @@ Tk_CoordsToWindow(
}
winPtr = nextPtr;
}
+ if (winPtr->mainPtr != ((TkWindow *) tkwin)->mainPtr) {
+ return NULL;
+ }
return (Tk_Window) winPtr;
}
@@ -4710,7 +4888,6 @@ Tk_MoveToplevelWindow(
wmPtr->x = x;
wmPtr->y = y;
wmPtr->flags |= WM_MOVE_PENDING;
- // wmPtr->flags &= ~(WM_NEGATIVE_X|WM_NEGATIVE_Y);
if (!(wmPtr->sizeHintsFlags & (USPosition|PPosition))) {
wmPtr->sizeHintsFlags |= USPosition;
wmPtr->flags |= WM_UPDATE_SIZE_HINTS;
@@ -5147,14 +5324,14 @@ TkSetWMName(
*----------------------------------------------------------------------
*/
-Window
+Tk_Window
TkGetTransientMaster(
TkWindow *winPtr)
{
if (winPtr->wmInfoPtr != NULL) {
- return winPtr->wmInfoPtr->master;
+ return (Tk_Window)winPtr->wmInfoPtr->master;
}
- return None;
+ return NULL;
}
/*
@@ -6197,8 +6374,10 @@ XSetInputFocus(
*
* TkpChangeFocus --
*
- * This procedure is a stub on the Mac because we always own the focus if
- * we are a front most application.
+ * This function is called when Tk moves focus from one window to another.
+ * It should be passed a non-embedded TopLevel. That toplevel gets raised
+ * to the top of the Tk stacking order and the associated NSWindow is
+ * ordered Front.
*
* Results:
* The return value is the serial number of the command that changed the
@@ -6389,7 +6568,7 @@ TkMacOSXApplyWindowAttributes(
{
WmInfo *wmPtr = winPtr->wmInfoPtr;
ApplyWindowAttributeFlagChanges(winPtr, macWindow, 0, 0, 0, 1);
- if (wmPtr->master != None || winPtr->atts.override_redirect) {
+ if (wmPtr->master != NULL || winPtr->atts.override_redirect) {
ApplyMasterOverrideChanges(winPtr, macWindow);
}
}
@@ -6526,7 +6705,7 @@ ApplyWindowAttributeFlagChanges(
*/
if ((winPtr->atts.override_redirect) ||
- (wmPtr->master != None) ||
+ (wmPtr->master != NULL) ||
(winPtr->wmInfoPtr->macClass == kHelpWindowClass)) {
b |= (NSWindowCollectionBehaviorCanJoinAllSpaces |
NSWindowCollectionBehaviorFullScreenAuxiliary);
@@ -6603,6 +6782,7 @@ ApplyMasterOverrideChanges(
int oldFlags = wmPtr->flags;
unsigned long styleMask;
NSRect structureRect;
+ NSWindow *parentWindow;
if (!macWindow && winPtr->window != None &&
TkMacOSXHostToplevelExists(winPtr)) {
@@ -6643,7 +6823,6 @@ ApplyMasterOverrideChanges(
}
}
if (macWindow) {
- NSWindow *parentWindow = [macWindow parentWindow];
structureRect = [NSWindow frameRectForContentRect:NSZeroRect
styleMask:styleMask];
@@ -6662,7 +6841,7 @@ ApplyMasterOverrideChanges(
if (wmPtr->hints.initial_state == NormalState) {
[macWindow orderFront:nil];
}
- if (wmPtr->master != None) {
+ if (wmPtr->master != NULL) {
wmPtr->flags |= WM_TOPMOST;
} else {
wmPtr->flags &= ~WM_TOPMOST;
@@ -6678,29 +6857,47 @@ ApplyMasterOverrideChanges(
wmPtr->flags &= ~WM_TOPMOST;
}
if (wmPtr->master != None) {
- TkDisplay *dispPtr = TkGetDisplayList();
- TkWindow *masterWinPtr = (TkWindow *)
- Tk_IdToWindow(dispPtr->display, wmPtr->master);
-
+ TkWindow *masterWinPtr = (TkWindow *)wmPtr->master;
if (masterWinPtr && masterWinPtr->window != None &&
TkMacOSXHostToplevelExists(masterWinPtr)) {
- NSWindow *masterMacWin =
- TkMacOSXDrawableWindow(masterWinPtr->window);
+ NSWindow *masterMacWin = TkMacOSXDrawableWindow(
+ masterWinPtr->window);
+
+ /*
+ * Try to add the transient window as a child window of the
+ * master. A child NSWindow retains its relative position with
+ * respect to the parent when the parent is moved. This is
+ * pointless if the parent is offscreen, and adding a child to
+ * an offscreen window causes the parent to be displayed as a
+ * zombie. So we only do this if the parent is visible.
+ */
+
+ if (masterMacWin &&
+ [masterMacWin isVisible] &&
+ (winPtr->flags & TK_MAPPED)) {
+
+ /*
+ * If the transient is already a child of some other window,
+ * remove it.
+ */
- if (masterMacWin && masterMacWin != parentWindow &&
- (winPtr->flags & TK_MAPPED)) {
- if (parentWindow) {
+ parentWindow = [macWindow parentWindow];
+ if (parentWindow && parentWindow != masterMacWin) {
[parentWindow removeChildWindow:macWindow];
}
+
[masterMacWin addChildWindow:macWindow
- ordered:NSWindowAbove];
- if (wmPtr->flags & WM_TOPMOST) {
- [macWindow setLevel:kCGUtilityWindowLevel];
+ ordered:NSWindowAbove];
}
- }
}
- } else if (parentWindow) {
- [parentWindow removeChildWindow:macWindow];
+ } else {
+ parentWindow = [macWindow parentWindow];
+ if (parentWindow) {
+ [parentWindow removeChildWindow:macWindow];
+ }
+ }
+ if (wmPtr->flags & WM_TOPMOST) {
+ [macWindow setLevel:kCGUtilityWindowLevel];
}
ApplyWindowAttributeFlagChanges(winPtr, macWindow, oldAttributes,
oldFlags, 0, 0);
diff --git a/macosx/tkMacOSXWm.h b/macosx/tkMacOSXWm.h
index 43f1a7a..5f07fe6 100644
--- a/macosx/tkMacOSXWm.h
+++ b/macosx/tkMacOSXWm.h
@@ -36,6 +36,17 @@ typedef struct ProtocolHandler {
* THE LAST FIELD OF THE STRUCTURE. */
} ProtocolHandler;
+/* The following data structure is used in the TkWmInfo to maintain a list of all of the
+ * transient windows belonging to a given master.
+ */
+
+typedef struct Transient {
+ TkWindow *winPtr;
+ int flags;
+ struct Transient *nextPtr;
+} Transient;
+
+#define WITHDRAWN_BY_MASTER 0x1
/*
* A data structure of the following type holds window-manager-related
@@ -54,7 +65,7 @@ typedef struct TkWmInfo {
Tk_Uid titleUid; /* Title to display in window caption. If NULL,
* use name of widget. */
char *iconName; /* Name to display in icon. */
- Window master; /* Master window for TRANSIENT_FOR property, or
+ Tk_Window master; /* Master window for TRANSIENT_FOR property, or
* None. */
XWMHints hints; /* Various pieces of information for window
* manager. */
@@ -62,14 +73,13 @@ typedef struct TkWmInfo {
* (corresponds to hints.window_group).
* Malloc-ed. Note: this field doesn't get
* updated if leader is destroyed. */
- char *masterWindowName; /* Path name of window specified as master in
- * "wm transient" command, or NULL. Malloc-ed.
- * Note: this field doesn't get updated if
- * masterWindowName is destroyed. */
Tk_Window icon; /* Window to use as icon for this window, or
* NULL. */
Tk_Window iconFor; /* Window for which this window is icon, or
* NULL if this isn't an icon for anyone. */
+ Transient *transientPtr; /* First item in a list of all transient windows
+ * belonging to this window, or NULL if there
+ * are no transients. */
/*
* Information used to construct an XSizeHints structure for the window
diff --git a/tests/imgPhoto.test b/tests/imgPhoto.test
index df97185..8ab555f 100644
--- a/tests/imgPhoto.test
+++ b/tests/imgPhoto.test
@@ -1754,6 +1754,39 @@ test imgPhoto-14.5 {Bug [fbaed1f66b] - GIF decoder with deferred clear code} -se
image create photo -file $fileName -format "gif -index 2"
} -returnCodes error -result {no image data for this index}
+test imgPhoto-14.6 {Access Subimage after Subimage with buffer overflow. Ticket 4da2191b} -setup {
+ set data {
+ R0lGODlhYwA5APcAAAAAAIAAAACAAICAAAAAgIAAgACAgICAgAysnGy8hKzM
+ hASs3MTcjAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDAwP8AAAD/
+ AP//AAAA//8A/wD//////ywAAAAAYwA5AAAI/wAZCBxIsKDBgwgTKlzIsKHD
+ hxAjSpxIsaLFixgzatzIsaPHjyBDihxJsqTJkyhTqlzJsqXLlzBjypxJs6bN
+ mzhz6tzJs6fPn0CDCh1KtKhRiwoSKEXAtGlTpUqPGkyagOmCq1edNsWalWkC
+ BUSXIuDqFepBqFWtZv3KU+zYrkrBSqT6dgECtjOTbu16NwFHvV3lshRLti/J
+ qlgRCE6ZuO9ik4Dt+k0ZVyZiyVIvXr77ODPEy5g9T4zMWfTEzXdNz1VbWvXn
+ uqldP1TAOrbshqBb314Y2W7n3Qdpv7UNPCHpycUVbv6dnODy5sqzQldIe8H0
+ hciva9/Ovbv37+BzBgE7ACH5BAFkAAMALAAAAAAEAAQAAAMEKLrckgA7
+ }
+} -body {
+ image create photo photo1 -data $data -format "GIF -index 1"
+} -cleanup {
+ catch {image delete photo1}
+} -result photo1
+
test imgPhoto-15.1 {photo images can fail to allocate memory gracefully} -constraints {
nonPortable
} -body {
diff --git a/tests/menu.test b/tests/menu.test
index 7101e21..87d8a9e 100644
--- a/tests/menu.test
+++ b/tests/menu.test
@@ -1614,7 +1614,7 @@ test menu-3.47 {MenuWidgetCmd procedure, "post" option} -setup {
.m1 post
} -cleanup {
destroy .m1
-} -returnCodes error -result {wrong # args: should be ".m1 post x y"}
+} -returnCodes error -result {wrong # args: should be ".m1 post x y ?index?"}
test menu-3.48 {MenuWidgetCmd procedure, "post" option} -setup {
destroy .m1
} -body {
diff --git a/tests/menubut.test b/tests/menubut.test
index d7ff2e3..a9d0656 100644
--- a/tests/menubut.test
+++ b/tests/menubut.test
@@ -542,7 +542,11 @@ test menubutton-6.1 {MenuButtonCmdDeletedProc procedure} -setup {
deleteWindows
} -result {{} {}}
-
+if {[tk windowingsystem] == "aqua"} {
+ set extraWidth 36
+} else {
+ set extraWidth 0
+}
test menubutton-7.1 {ComputeMenuButtonGeometry procedure} -constraints {
testImageType
} -setup {
@@ -555,33 +559,33 @@ test menubutton-7.1 {ComputeMenuButtonGeometry procedure} -constraints {
} -cleanup {
deleteWindows
imageCleanup
-} -result {38 23}
+} -result [list [expr {38 + $extraWidth}] 23]
test menubutton-7.2 {ComputeMenuButtonGeometry procedure} -constraints {
testImageType
} -setup {
deleteWindows
image create test image1
} -body {
- menubutton .mb -image image1 -bd 1 -highlightthickness 2
+ menubutton .mb -image image1 -bd 3 -highlightthickness 1
pack .mb
list [winfo reqwidth .mb] [winfo reqheight .mb]
} -cleanup {
deleteWindows
imageCleanup
-} -result {36 21}
+} -result [list [expr {38 + $extraWidth}] 23]
test menubutton-7.3 {ComputeMenuButtonGeometry procedure} -constraints {
testImageType
} -setup {
deleteWindows
image create test image1
} -body {
- menubutton .mb -image image1 -bd 0 -highlightthickness 2 -padx 5 -pady 5
+ menubutton .mb -image image1 -bd 1 -highlightthickness 3 -padx 5 -pady 5
pack .mb
list [winfo reqwidth .mb] [winfo reqheight .mb]
} -cleanup {
deleteWindows
imageCleanup
-} -result {34 19}
+} -result [list [expr {38 + $extraWidth}] 23]
test menubutton-7.4 {ComputeMenuButtonGeometry procedure} -constraints {
testImageType
} -setup {
@@ -595,7 +599,7 @@ test menubutton-7.4 {ComputeMenuButtonGeometry procedure} -constraints {
} -cleanup {
deleteWindows
imageCleanup
-} -result {48 23}
+} -result [list [expr {48 + $extraWidth}] 23]
test menubutton-7.5 {ComputeMenuButtonGeometry procedure} -constraints {
testImageType
} -setup {
@@ -609,7 +613,7 @@ test menubutton-7.5 {ComputeMenuButtonGeometry procedure} -constraints {
} -cleanup {
deleteWindows
imageCleanup
-} -result {38 38}
+} -result [list [expr {38 + $extraWidth}] 38]
test menubutton-7.6 {ComputeMenuButtonGeometry procedure} -setup {
deleteWindows
} -body {
@@ -619,7 +623,7 @@ test menubutton-7.6 {ComputeMenuButtonGeometry procedure} -setup {
list [winfo reqwidth .mb] [winfo reqheight .mb]
} -cleanup {
deleteWindows
-} -result {25 35}
+} -result [list [expr {25 + $extraWidth}] 35]
test menubutton-7.7 {ComputeMenuButtonGeometry procedure} -setup {
deleteWindows
} -body {
@@ -629,7 +633,7 @@ test menubutton-7.7 {ComputeMenuButtonGeometry procedure} -setup {
list [winfo reqwidth .mb] [winfo reqheight .mb]
} -cleanup {
deleteWindows
-} -result {46 33}
+} -result [list [expr {46 + $extraWidth}] 33]
test menubutton-7.8 {ComputeMenuButtonGeometry procedure} -setup {
deleteWindows
} -body {
@@ -639,7 +643,7 @@ test menubutton-7.8 {ComputeMenuButtonGeometry procedure} -setup {
list [winfo reqwidth .mb] [winfo reqheight .mb]
} -cleanup {
deleteWindows
-} -result {23 56}
+} -result [list [expr {23 + $extraWidth}] 56]
test menubutton-7.9 {ComputeMenuButtonGeometry procedure} -constraints {
fonts
} -setup {
diff --git a/tests/scale.test b/tests/scale.test
index d22c4c3..e9dbc65 100644
--- a/tests/scale.test
+++ b/tests/scale.test
@@ -1104,78 +1104,78 @@ test scale-13.6 {SetScaleValue procedure} -body {
destroy .s
pack [scale .s]
update
-test scale-14.1 {RoundToResolution procedure} -body {
+test scale-14.1 {RoundValueToResolution procedure} -body {
.s configure -from 0 -to 100 -sliderlength 10 -length 114 -bd 2 \
-orient horizontal -resolution 4.0
update
.s get 84 152
} -result 72
-test scale-14.2 {RoundToResolution procedure} -body {
+test scale-14.2 {RoundValueToResolution procedure} -body {
.s configure -from 0 -to 100 -sliderlength 10 -length 114 -bd 2 \
-orient horizontal -resolution 4.0
update
.s get 86 152
} -result 76
-test scale-14.3 {RoundToResolution procedure} -body {
+test scale-14.3 {RoundValueToResolution procedure} -body {
.s configure -from 100 -to 0 -sliderlength 10 -length 114 -bd 2 \
-orient horizontal -resolution 4.0
update
.s get 84 152
} -result 28
-test scale-14.4 {RoundToResolution procedure} -body {
+test scale-14.4 {RoundValueToResolution procedure} -body {
.s configure -from 100 -to 0 -sliderlength 10 -length 114 -bd 2 \
-orient horizontal -resolution 4.0
update
.s get 86 152
} -result 24
-test scale-14.5 {RoundToResolution procedure} -body {
+test scale-14.5 {RoundValueToResolution procedure} -body {
.s configure -from -100 -to 0 -sliderlength 10 -length 114 -bd 2 \
-orient horizontal -resolution 4.0
update
.s get 84 152
} -result {-28}
-test scale-14.6 {RoundToResolution procedure} -body {
+test scale-14.6 {RoundValueToResolution procedure} -body {
.s configure -from -100 -to 0 -sliderlength 10 -length 114 -bd 2 \
-orient horizontal -resolution 4.0
update
.s get 86 152
} -result {-24}
-test scale-14.7 {RoundToResolution procedure} -body {
+test scale-14.7 {RoundValueToResolution procedure} -body {
.s configure -from 0 -to -100 -sliderlength 10 -length 114 -bd 2 \
-orient horizontal -resolution 4.0
update
.s get 84 152
} -result {-72}
-test scale-14.8 {RoundToResolution procedure} -body {
+test scale-14.8 {RoundValueToResolution procedure} -body {
.s configure -from 0 -to -100 -sliderlength 10 -length 114 -bd 2 \
-orient horizontal -resolution 4.0
update
.s get 86 152
} -result {-76}
-test scale-14.9 {RoundToResolution procedure} -body {
+test scale-14.9 {RoundValueToResolution procedure} -body {
.s configure -from 0 -to 2.25 -sliderlength 10 -length 114 -bd 2 \
-orient horizontal -resolution 0
update
.s get 84 152
} -result {1.64}
-test scale-14.10 {RoundToResolution procedure} -body {
+test scale-14.10 {RoundValueToResolution procedure} -body {
.s configure -from 0 -to 2.25 -sliderlength 10 -length 114 -bd 2 \
-orient horizontal -resolution 0
update
.s get 86 152
} -result {1.69}
-test scale-14.11 {RoundToResolution procedure} -body {
+test scale-14.11 {RoundValueToResolution procedure} -body {
.s configure -from 0 -to 225 -sliderlength 10 -length 114 -bd 2 \
-orient horizontal -resolution 0 -digits 5
update
.s get 84 152
} -result {164.25}
-test scale-14.12 {RoundToResolution procedure} -body {
+test scale-14.12 {RoundValueToResolution procedure} -body {
.s configure -from 0 -to 225 -sliderlength 10 -length 114 -bd 2 \
-orient horizontal -resolution 0 -digits 5
update
@@ -1183,6 +1183,41 @@ test scale-14.12 {RoundToResolution procedure} -body {
} -result {168.75}
destroy .s
+test scale-14.13 {RoundValueToResolution procedure, round-off errors} -setup {
+ # see [220665ffff], and duplicates [220265ffff] and [779559ffff]
+ set x NotSet
+ pack [scale .s -orient horizontal -resolution .1 -from -180 -to 180 -command "set x"]
+ update
+} -body {
+ .s configure -background red
+ update
+ set x
+} -cleanup {
+ destroy .s
+} -result {NotSet}
+
+test scale-14a.1 {RoundValueToResolution, RoundIntervalToResolution procedures} -setup {
+ pack [scale .s -orient horizontal]
+ update
+} -body {
+ .s configure -length 400 -bd 0 -from 1 -to 9 -resolution 2 -tickinterval 1
+ update
+ .s get 200 0
+} -cleanup {
+ destroy .s
+} -result {5}
+test scale-14a.2 {RoundValueToResolution, RoundIntervalToResolution procedures} -setup {
+ pack [scale .s -orient horizontal]
+ update
+} -body {
+ .s configure -length 400 -bd 0 -from -1.5 -to 1.5 -resolution 1 \
+ -tickinterval 1 -digits 2
+ update
+ .s get 250 0
+} -cleanup {
+ destroy .s
+} -result {0.5}
+
test scale-15.1 {ScaleVarProc procedure} -setup {
deleteWindows
diff --git a/tests/send.test b/tests/send.test
index 945d4d0..403a207 100644
--- a/tests/send.test
+++ b/tests/send.test
@@ -197,7 +197,8 @@ test send-7.4 {Tk_SetAppName procedure, name in use} {secureserver testsend} {
list [tk appname foo] [testsend prop root InterpRegistry]
} "{foo #4} {$commId foo #4\n$id foo\n$id foo #2\n$id foo #3\n}"
-test send-8.1 {Tk_SendCmd procedure, options} {secureserver} {
+#macOS does not send to other processes
+test send-8.1 {Tk_SendCmd procedure, options} {secureserver notAqua} {
setupbg
set app [dobg {tk appname}]
set a 66
@@ -222,10 +223,11 @@ test send-8.2 {Tk_SendCmd procedure, options} {secureserver altDisplay} {
cleanupbg
set result
} {altDisplay homeDisplay}
-test send-8.3 {Tk_SendCmd procedure, options} {secureserver} {
+# Since macOS has no registry of interpreters, 8.3, 8.4 and 8.10 will fail.
+test send-8.3 {Tk_SendCmd procedure, options} {secureserver notAqua} {
list [catch {send -- -async foo bar baz} msg] $msg
} {1 {no application named "-async"}}
-test send-8.4 {Tk_SendCmd procedure, options} {secureserver} {
+test send-8.4 {Tk_SendCmd procedure, options} {secureserver notAqua} {
list [catch {send -gorp foo bar baz} msg] $msg
} {1 {no application named "-gorp"}}
test send-8.5 {Tk_SendCmd procedure, options} {secureserver} {
@@ -253,7 +255,7 @@ test send-8.9 {Tk_SendCmd procedure, local execution} {secureserver} {
"open bad_file"
invoked from within
"send [tk appname] open bad_file"} {posix enoent {no such file or directory}}}
-test send-8.10 {Tk_SendCmd procedure, no such interpreter} {secureserver} {
+test send-8.10 {Tk_SendCmd procedure, no such interpreter} {secureserver notAqua} {
list [catch {send bogus_name bogus_command} msg] $msg
} {1 {no application named "bogus_name"}}
@@ -542,7 +544,8 @@ test send-12.1 {TimeoutProc procedure} {secureserver testsend} {
catch {testsend prop root InterpRegistry ""}
-test send-12.2 {TimeoutProc procedure} {secureserver} {
+#macOS does not send to other processes
+test send-12.2 {TimeoutProc procedure} {secureserver notAqua} {
winfo interps
tk appname tktest
update
@@ -557,16 +560,17 @@ test send-12.2 {TimeoutProc procedure} {secureserver} {
set result
} {1 {target application died}}
+#macOS does not send to other processes
winfo interps
tk appname tktest
-test send-13.1 {DeleteProc procedure} {secureserver} {
+test send-13.1 {DeleteProc procedure} {secureserver notAqua} {
setupbg
set app [dobg {rename send {}; tk appname}]
set result [list [catch {send $app foo} msg] $msg [winfo interps]]
cleanupbg
set result
} {1 {no application named "tktest #2"} tktest}
-test send-13.2 {DeleteProc procedure} {secureserver} {
+test send-13.2 {DeleteProc procedure} {secureserver notAqua} {
winfo interps
tk appname tktest
rename send {}
diff --git a/tests/text.test b/tests/text.test
index 621a9eb..3314fc9 100644
--- a/tests/text.test
+++ b/tests/text.test
@@ -2948,11 +2948,13 @@ test text-11a.1 {TextWidgetCmd procedure, "pendingsync" option} -setup {
} -cleanup {
destroy .yt
} -result {1 {wrong # args: should be ".yt pendingsync"}}
+
test text-11a.2 {TextWidgetCmd procedure, "pendingsync" option} -setup {
destroy .top.yt .top
} -body {
toplevel .top
pack [text .top.yt]
+ update
set content {}
for {set i 1} {$i < 300} {incr i} {
append content [string repeat "$i " 15] \n
@@ -2990,9 +2992,11 @@ test text-11a.12 {TextWidgetCmd procedure, "sync" option} -setup {
} -body {
toplevel .top
pack [text .top.yt]
+ update
set content {}
+ # Use long lines so the line metrics will need updating.
for {set i 1} {$i < 30} {incr i} {
- append content [string repeat "$i " 15] \n
+ append content [string repeat "$i " 200] \n
}
.top.yt insert 1.0 $content
# wait for end of line metrics calculation to get correct $fraction1
@@ -3065,19 +3069,18 @@ test text-11a.31 {"<<WidgetViewSync>>" event} -setup {
for {set i 1} {$i < 300} {incr i} {
append content [string repeat "$i " 15] \n
}
- .top.yt insert 1.0 $content
+ # Sync the widget and process <<WidgetViewSync>> events before binding.
+ .top.yt sync
update
bind .top.yt <<WidgetViewSync>> { if {%d} {set yud(%W) 1} }
- # wait for end of line metrics calculation to get correct $fraction1
- # as a reference
- if {[.top.yt pendingsync]} {vwait yud(.top.yt)}
+ .top.yt insert 1.0 $content
.top.yt yview moveto 1
set fraction1 [lindex [.top.yt yview] 0]
set res [expr {$fraction1 > 0}]
.top.yt delete 1.0 end
.top.yt insert 1.0 $content
# synchronously wait for completion of line metrics calculation
- # and ensure the test is relevant
+ # and verify that the fractions agree.
set waited 0
if {[.top.yt pendingsync]} {set waited 1 ; vwait yud(.top.yt)}
lappend res $waited
@@ -3091,7 +3094,6 @@ test text-11a.31 {"<<WidgetViewSync>>" event} -setup {
test text-11a.41 {"sync" "pendingsync" and <<WidgetViewSync>>} -setup {
destroy .top.yt .top
} -body {
- set res {}
toplevel .top
pack [text .top.yt]
update
@@ -3099,15 +3101,21 @@ test text-11a.41 {"sync" "pendingsync" and <<WidgetViewSync>>} -setup {
for {set i 1} {$i < 300} {incr i} {
append content [string repeat "$i " 50] \n
}
+ # Sync the widget and process all <<WidgetViewSync>> events before binding.
+ .top.yt sync
+ update
bind .top.yt <<WidgetViewSync>> {lappend res Sync:%d}
+ set res {}
+ # The next line triggers <<WidgetViewSync>> with %d==0 i.e. out of sync.
.top.yt insert 1.0 $content
- vwait res ; # event dealt with by the event loop, with %d==0 i.e. we're out of sync
- # ensure the test is relevant
+ vwait res
+ # Verify that the line metrics are not up-to-date (pendingsync is 1).
lappend res "Pending:[.top.yt pendingsync]"
- # - <<WidgetViewSync>> fires when sync returns if there was pending syncs
- # - there is no more any pending sync after running 'sync'
+ # Update all line metrics by calling the sync command.
.top.yt sync
- vwait res ; # event dealt with by the event loop, with %d==1 i.e. we're in sync again
+ # <<WidgetViewSync>> should fire with %d==1 i.e. back in sync.
+ vwait res
+ # At this time the line metrics should be up-to-date (pendingsync is 0).
lappend res "Pending:[.top.yt pendingsync]"
set res
} -cleanup {
@@ -3122,6 +3130,7 @@ test text-11a.51 {<<WidgetViewSync>> calls TkSendVirtualEvent(),
set res {}
toplevel .top
pack [text .top.t]
+ update
for {set i 1} {$i < 10000} {incr i} {
.top.t insert end "Hello world!\n"
}
@@ -3477,6 +3486,12 @@ test text-14.18 {ConfigureText procedure} -constraints fonts -setup {
# minimum size and it was interfering with the size requested by the -setgrid.
# The "overrideredirect" gets rid of the titlebar so the toplevel can shrink
# to the appropriate size.
+# On macOS, however, there is no way to make the window overlap the menubar.
+if {[tk windowingsystem] == "aqua"} {
+ set minY 23
+} else {
+ set minY 0
+}
test text-14.19 {ConfigureText procedure} -setup {
toplevel .top
text .top.t -font {Courier -12} -borderwidth 2 -highlightthickness 2
@@ -3484,16 +3499,17 @@ test text-14.19 {ConfigureText procedure} -setup {
.top.t configure -width 20 -height 10 -setgrid 1
wm overrideredirect .top 1
pack .top.t
- wm geometry .top +0+0
+ wm geometry .top +0+$minY
update
wm geometry .top
} -cleanup {
destroy .top
-} -result {20x10+0+0}
+} -result "20x10+0+$minY"
# This test was failing on Windows because the title bar on .t was a certain
# minimum size and it was interfering with the size requested by the -setgrid.
# The "overrideredirect" gets rid of the titlebar so the toplevel can shrink
# to the appropriate size.
+# On macOS we again use minY as a workaround.
test text-14.20 {ConfigureText procedure} -setup {
toplevel .top
text .top.t -font {Courier -12} -borderwidth 2 -highlightthickness 2
@@ -3501,7 +3517,7 @@ test text-14.20 {ConfigureText procedure} -setup {
.top.t configure -width 20 -height 10 -setgrid 1
wm overrideredirect .top 1
pack .top.t
- wm geometry .top +0+0
+ wm geometry .top +0+$minY
update
set result [wm geometry .top]
wm geometry .top 15x8
@@ -3512,7 +3528,7 @@ test text-14.20 {ConfigureText procedure} -setup {
lappend result [wm geometry .top]
} -cleanup {
destroy .top
-} -result {20x10+0+0 15x8+0+0 15x8+0+0}
+} -result "20x10+0+$minY 15x8+0+$minY 15x8+0+$minY"
test text-15.1 {TextWorldChanged procedure, spacing options} -constraints {
@@ -7429,6 +7445,194 @@ test text-32.1 {line heights on creation} -setup {
destroy .t
} -result {1}
+test text-32.2 {peer widget -start, -end and deletion (bug 1630262)} -setup {
+ destroy .t .pt
+ set res {}
+} -body {
+ text .t
+ .t peer create .pt
+ for {set i 1} {$i < 100} {incr i} {
+ .t insert end "Line $i\n"
+ }
+ .t configure -startline 5
+ # none of the following delete shall crash
+ # (all did before fixing bug 1630262)
+ # 1. delete on the same line: line1 == line2 in DeleteIndexRange,
+ # and resetView is true neither for .t not for .pt
+ .pt delete 2.0 2.2
+ # 2. delete just one line: line1 < line2 in DeleteIndexRange,
+ # and resetView is true only for .t, not for .pt
+ .pt delete 2.0 3.0
+ # 3. delete several lines: line1 < line2 in DeleteIndexRange,
+ # and resetView is true only for .t, not for .pt
+ .pt delete 2.0 5.0
+ # 4. delete to the end line: line1 < line2 in DeleteIndexRange,
+ # and resetView is true only for .t, not for .pt
+ .pt delete 2.0 end
+ # this test succeeds provided there is no crash
+ set res 1
+} -cleanup {
+ destroy .pt
+} -result {1}
+
+test text-32.3 {peer widget -start, -end and deletion (bug 1630262)} -setup {
+ destroy .t .pt
+ set res {}
+} -body {
+ text .t
+ .t peer create .pt
+ for {set i 1} {$i < 100} {incr i} {
+ .t insert end "Line $i\n"
+ }
+ .t configure -startline 5
+ .pt configure -startline 3
+ # the following delete shall not crash
+ # (it did before fixing bug 1630262)
+ .pt delete 2.0 3.0
+ # moreover -startline shall be correct
+ # (was wrong before fixing bug 1630262)
+ lappend res [.t cget -start] [.pt cget -start]
+} -cleanup {
+ destroy .pt
+} -result {4 3}
+
+test text-32.4 {peer widget -start, -end and deletion (bug 1630262)} -setup {
+ destroy .t .pt
+ set res {}
+} -body {
+ text .t
+ .t peer create .pt
+ for {set i 1} {$i < 100} {incr i} {
+ .t insert end "Line $i\n"
+ }
+ .t configure -startline 5 -endline 15
+ .pt configure -startline 8 -endline 12
+ # .pt now shows a range entirely inside the range of .pt
+ # from .t, delete lines located after [.pt cget -end]
+ .t delete 9.0 10.0
+ # from .t, delete lines straddling [.pt cget -end]
+ .t delete 6.0 9.0
+ lappend res [.t cget -start] [.t cget -end] [.pt cget -start] [.pt cget -end]
+ .t configure -startline 5 -endline 12
+ .pt configure -startline 8 -endline 12
+ # .pt now shows again a range entirely inside the range of .pt
+ # from .t, delete lines located before [.pt cget -start]
+ .t delete 2.0 3.0
+ # from .t, delete lines straddling [.pt cget -start]
+ .t delete 2.0 5.0
+ lappend res [.t cget -start] [.t cget -end] [.pt cget -start] [.pt cget -end]
+ .t configure -startline 22 -endline 31
+ .pt configure -startline 42 -endline 51
+ # .t now shows a range entirely before the range of .pt
+ # from .t, delete some lines, then do it from .pt
+ .t delete 2.0 3.0
+ .t delete 2.0 5.0
+ .pt delete 2.0 5.0
+ lappend res [.t cget -start] [.t cget -end] [.pt cget -start] [.pt cget -end]
+ .t configure -startline 55 -endline 75
+ .pt configure -startline 60 -endline 70
+ # .pt now shows a range entirely inside the range of .t
+ # from .t, delete a range straddling the entire range of .pt
+ .t delete 3.0 18.0
+ lappend res [.t cget -start] [.t cget -end] [.pt cget -start] [.pt cget -end]
+} -cleanup {
+ destroy .pt .t
+} -result {5 11 8 10 5 8 6 8 22 27 38 44 55 60 57 57}
+
+test text-32.2 {peer widget -start, -end and deletion (bug 1630262)} -setup {
+ destroy .t .pt
+ set res {}
+} -body {
+ text .t
+ .t peer create .pt
+ for {set i 1} {$i < 100} {incr i} {
+ .t insert end "Line $i\n"
+ }
+ .t configure -startline 5
+ # none of the following delete shall crash
+ # (all did before fixing bug 1630262)
+ # 1. delete on the same line: line1 == line2 in DeleteIndexRange,
+ # and resetView is true neither for .t not for .pt
+ .pt delete 2.0 2.2
+ # 2. delete just one line: line1 < line2 in DeleteIndexRange,
+ # and resetView is true only for .t, not for .pt
+ .pt delete 2.0 3.0
+ # 3. delete several lines: line1 < line2 in DeleteIndexRange,
+ # and resetView is true only for .t, not for .pt
+ .pt delete 2.0 5.0
+ # 4. delete to the end line: line1 < line2 in DeleteIndexRange,
+ # and resetView is true only for .t, not for .pt
+ .pt delete 2.0 end
+ # this test succeeds provided there is no crash
+ set res 1
+} -cleanup {
+ destroy .pt
+} -result {1}
+
+test text-32.3 {peer widget -start, -end and deletion (bug 1630262)} -setup {
+ destroy .t .pt
+ set res {}
+} -body {
+ text .t
+ .t peer create .pt
+ for {set i 1} {$i < 100} {incr i} {
+ .t insert end "Line $i\n"
+ }
+ .t configure -startline 5
+ .pt configure -startline 3
+ # the following delete shall not crash
+ # (it did before fixing bug 1630262)
+ .pt delete 2.0 3.0
+ # moreover -startline shall be correct
+ # (was wrong before fixing bug 1630262)
+ lappend res [.t cget -start] [.pt cget -start]
+} -cleanup {
+ destroy .pt
+} -result {4 3}
+
+test text-32.4 {peer widget -start, -end and deletion (bug 1630262)} -setup {
+ destroy .t .pt
+ set res {}
+} -body {
+ text .t
+ .t peer create .pt
+ for {set i 1} {$i < 100} {incr i} {
+ .t insert end "Line $i\n"
+ }
+ .t configure -startline 5 -endline 15
+ .pt configure -startline 8 -endline 12
+ # .pt now shows a range entirely inside the range of .pt
+ # from .t, delete lines located after [.pt cget -end]
+ .t delete 9.0 10.0
+ # from .t, delete lines straddling [.pt cget -end]
+ .t delete 6.0 9.0
+ lappend res [.t cget -start] [.t cget -end] [.pt cget -start] [.pt cget -end]
+ .t configure -startline 5 -endline 12
+ .pt configure -startline 8 -endline 12
+ # .pt now shows again a range entirely inside the range of .pt
+ # from .t, delete lines located before [.pt cget -start]
+ .t delete 2.0 3.0
+ # from .t, delete lines straddling [.pt cget -start]
+ .t delete 2.0 5.0
+ lappend res [.t cget -start] [.t cget -end] [.pt cget -start] [.pt cget -end]
+ .t configure -startline 22 -endline 31
+ .pt configure -startline 42 -endline 51
+ # .t now shows a range entirely before the range of .pt
+ # from .t, delete some lines, then do it from .pt
+ .t delete 2.0 3.0
+ .t delete 2.0 5.0
+ .pt delete 2.0 5.0
+ lappend res [.t cget -start] [.t cget -end] [.pt cget -start] [.pt cget -end]
+ .t configure -startline 55 -endline 75
+ .pt configure -startline 60 -endline 70
+ # .pt now shows a range entirely inside the range of .t
+ # from .t, delete a range straddling the entire range of .pt
+ .t delete 3.0 18.0
+ lappend res [.t cget -start] [.t cget -end] [.pt cget -start] [.pt cget -end]
+} -cleanup {
+ destroy .pt .t
+} -result {5 11 8 10 5 8 6 8 22 27 38 44 55 60 57 57}
+
test text-33.1 {TextWidgetCmd procedure, "peer" option} -setup {
text .t
@@ -7561,100 +7765,6 @@ test text-34.1 {peer widget -start, -end and selection} -setup {
destroy .t
} -result {{10.0 20.0} {6.0 16.0} {6.0 11.0} {1.0 6.0} {1.0 2.0} {} {10.0 20.0}}
-test text-32.2 {peer widget -start, -end and deletion (bug 1630262)} -setup {
- destroy .t .pt
- set res {}
-} -body {
- text .t
- .t peer create .pt
- for {set i 1} {$i < 100} {incr i} {
- .t insert end "Line $i\n"
- }
- .t configure -startline 5
- # none of the following delete shall crash
- # (all did before fixing bug 1630262)
- # 1. delete on the same line: line1 == line2 in DeleteIndexRange,
- # and resetView is true neither for .t not for .pt
- .pt delete 2.0 2.2
- # 2. delete just one line: line1 < line2 in DeleteIndexRange,
- # and resetView is true only for .t, not for .pt
- .pt delete 2.0 3.0
- # 3. delete several lines: line1 < line2 in DeleteIndexRange,
- # and resetView is true only for .t, not for .pt
- .pt delete 2.0 5.0
- # 4. delete to the end line: line1 < line2 in DeleteIndexRange,
- # and resetView is true only for .t, not for .pt
- .pt delete 2.0 end
- # this test succeeds provided there is no crash
- set res 1
-} -cleanup {
- destroy .pt
-} -result {1}
-
-test text-32.3 {peer widget -start, -end and deletion (bug 1630262)} -setup {
- destroy .t .pt
- set res {}
-} -body {
- text .t
- .t peer create .pt
- for {set i 1} {$i < 100} {incr i} {
- .t insert end "Line $i\n"
- }
- .t configure -startline 5
- .pt configure -startline 3
- # the following delete shall not crash
- # (it did before fixing bug 1630262)
- .pt delete 2.0 3.0
- # moreover -startline shall be correct
- # (was wrong before fixing bug 1630262)
- lappend res [.t cget -start] [.pt cget -start]
-} -cleanup {
- destroy .pt
-} -result {4 3}
-
-test text-32.4 {peer widget -start, -end and deletion (bug 1630262)} -setup {
- destroy .t .pt
- set res {}
-} -body {
- text .t
- .t peer create .pt
- for {set i 1} {$i < 100} {incr i} {
- .t insert end "Line $i\n"
- }
- .t configure -startline 5 -endline 15
- .pt configure -startline 8 -endline 12
- # .pt now shows a range entirely inside the range of .pt
- # from .t, delete lines located after [.pt cget -end]
- .t delete 9.0 10.0
- # from .t, delete lines straddling [.pt cget -end]
- .t delete 6.0 9.0
- lappend res [.t cget -start] [.t cget -end] [.pt cget -start] [.pt cget -end]
- .t configure -startline 5 -endline 12
- .pt configure -startline 8 -endline 12
- # .pt now shows again a range entirely inside the range of .pt
- # from .t, delete lines located before [.pt cget -start]
- .t delete 2.0 3.0
- # from .t, delete lines straddling [.pt cget -start]
- .t delete 2.0 5.0
- lappend res [.t cget -start] [.t cget -end] [.pt cget -start] [.pt cget -end]
- .t configure -startline 22 -endline 31
- .pt configure -startline 42 -endline 51
- # .t now shows a range entirely before the range of .pt
- # from .t, delete some lines, then do it from .pt
- .t delete 2.0 3.0
- .t delete 2.0 5.0
- .pt delete 2.0 5.0
- lappend res [.t cget -start] [.t cget -end] [.pt cget -start] [.pt cget -end]
- .t configure -startline 55 -endline 75
- .pt configure -startline 60 -endline 70
- # .pt now shows a range entirely inside the range of .t
- # from .t, delete a range straddling the entire range of .pt
- .t delete 3.0 18.0
- lappend res [.t cget -start] [.t cget -end] [.pt cget -start] [.pt cget -end]
-} -cleanup {
- destroy .pt .t
-} -result {5 11 8 10 5 8 6 8 22 27 38 44 55 60 57 57}
-
test text-35.1 {widget dump -command alters tags} -setup {
proc Dumpy {key value index} {
#puts "KK: $key, $value"
diff --git a/tests/unixButton.test b/tests/unixButton.test
index 36064f9..9d54707 100644
--- a/tests/unixButton.test
+++ b/tests/unixButton.test
@@ -35,7 +35,15 @@ proc bogusTrace args {
error "trace aborted"
}
-
+if {[tk windowingsystem] eq "aqua"} {
+ set smallIndicator 20
+ set bigIndicator 20
+ set defaultBorder 10
+} else {
+ set smallIndicator 27
+ set bigIndicator 40
+ set defaultBorder 20
+}
test unixbutton-1.1 {TkpComputeButtonGeometry procedure} -constraints {
unix testImageType
} -setup {
@@ -57,7 +65,10 @@ test unixbutton-1.1 {TkpComputeButtonGeometry procedure} -constraints {
} -cleanup {
deleteWindows
image delete image1
-} -result {68 48 74 54 112 52 112 52}
+} -result [list 68 48 \
+ 74 54 \
+ [expr {72 + $bigIndicator}] 52 \
+ [expr {72 + $bigIndicator}] 52]
test unixbutton-1.2 {TkpComputeButtonGeometry procedure} -constraints {
unix
} -setup {
@@ -75,7 +86,10 @@ test unixbutton-1.2 {TkpComputeButtonGeometry procedure} -constraints {
[winfo reqwidth .b4] [winfo reqheight .b4]
} -cleanup {
deleteWindows
-} -result {23 33 29 39 54 37 54 37}
+} -result [list 23 33 \
+ 29 39 \
+ [expr {27 + $smallIndicator}] 37 \
+ [expr {27 + $smallIndicator}] 37]
test unixbutton-1.3 {TkpComputeButtonGeometry procedure} -constraints {
unix
} -setup {
@@ -186,7 +200,7 @@ test unixbutton-1.9 {TkpComputeButtonGeometry procedure} -constraints {
list [winfo reqwidth .b2] [winfo reqheight .b2]
} -cleanup {
deleteWindows
-} -result {37 47}
+} -result [list [expr {17 + $defaultBorder}] [expr {27 + $defaultBorder}]]
test unixbutton-1.10 {TkpComputeButtonGeometry procedure} -constraints {
unix
} -setup {
@@ -196,7 +210,7 @@ test unixbutton-1.10 {TkpComputeButtonGeometry procedure} -constraints {
list [winfo reqwidth .b2] [winfo reqheight .b2]
} -cleanup {
deleteWindows
-} -result {37 47}
+} -result [list [expr {17 + $defaultBorder}] [expr {27 + $defaultBorder}]]
test unixbutton-1.11 {TkpComputeButtonGeometry procedure} -constraints {
unix
} -setup {
diff --git a/tests/unixEmbed.test b/tests/unixEmbed.test
index 9916df2..99f7265 100644
--- a/tests/unixEmbed.test
+++ b/tests/unixEmbed.test
@@ -11,6 +11,37 @@ eval tcltest::configure $argv
tcltest::loadTestedCommands
namespace import -force tcltest::test
+namespace eval ::_test_tmp {}
+
+# ------------------------------------------------------------------------------
+# Proc ::_test_tmp::testInterp
+# ------------------------------------------------------------------------------
+# Command that creates an unsafe child interpreter and tries to load Tk.
+# This code is borrowed from safePrimarySelection.test
+# This is necessary for loading Tktest if the tests are done in the build
+# directory without installing Tk. In that case the usual auto_path loading
+# mechanism cannot work because the tk binary is not where pkgIndex.tcl says
+# it is.
+# ------------------------------------------------------------------------------
+
+namespace eval ::_test_tmp {
+ variable TkLoadCmd
+}
+
+foreach pkg [info loaded] {
+ if {[lindex $pkg 1] eq "Tk"} {
+ set ::_test_tmp::TkLoadCmd [list load {*}$pkg]
+ break
+ }
+}
+
+proc ::_test_tmp::testInterp {name} {
+ variable TkLoadCmd
+ interp create $name
+ $name eval [list set argv [list -name $name]]
+ catch {{*}$TkLoadCmd $name}
+}
+
setupbg
dobg {wm withdraw .}
@@ -97,7 +128,7 @@ test unixEmbed-1.4 {TkpUseWindow procedure, inheriting colormap} -constraints {
} -result {1}
test unixEmbed-1.5 {TkpUseWindow procedure, creating Container records} -constraints {
- unix testembed
+ unix testembed notAqua
} -setup {
deleteWindows
} -body {
@@ -113,8 +144,29 @@ test unixEmbed-1.5 {TkpUseWindow procedure, creating Container records} -constra
} -cleanup {
deleteWindows
} -result {{{XXX {} {} .t}} 0}
+test unixEmbed-1.5a {TkpUseWindow procedure, creating Container records} -constraints {
+ unix testembed
+} -setup {
+ deleteWindows
+ catch {interp delete slave}
+ ::_test_tmp::testInterp slave
+ load {} Tktest slave
+} -body {
+ frame .f1 -container 1 -width 200 -height 50
+ frame .f2 -container 1 -width 200 -height 50
+ pack .f1 .f2
+ slave alias w winfo id .f1
+ slave eval {
+ destroy [winfo child .]
+ toplevel .t -use [w]
+ list [testembed] [expr {[lindex [lindex [testembed all] 0] 0] - [w]}]
+ }
+} -cleanup {
+ interp delete slave
+ deleteWindows
+} -result {{{XXX {} {} .t}} 0}
test unixEmbed-1.6 {TkpUseWindow procedure, creating Container records} -constraints {
- unix testembed
+ unix testembed notAqua
} -setup {
deleteWindows
} -body {
@@ -132,6 +184,29 @@ test unixEmbed-1.6 {TkpUseWindow procedure, creating Container records} -constra
} -cleanup {
deleteWindows
} -result {{XXX {} {} .t2} {XXX {} {} .t1}}
+test unixEmbed-1.6a {TkpUseWindow procedure, creating Container records} -constraints {
+ unix testembed
+} -setup {
+ deleteWindows
+ catch {interp delete slave}
+ ::_test_tmp::testInterp slave
+ load {} Tktest slave
+} -body {
+ frame .f1 -container 1 -width 200 -height 50
+ frame .f2 -container 1 -width 200 -height 50
+ pack .f1 .f2
+ slave alias w1 winfo id .f1
+ slave alias w2 winfo id .f2
+ slave eval {
+ destroy [winfo child .]
+ toplevel .t1 -use [w1]
+ toplevel .t2 -use [w2]
+ testembed
+ }
+} -cleanup {
+ interp delete slave
+ deleteWindows
+} -result {{XXX {} {} .t2} {XXX {} {} .t1}}
test unixEmbed-1.7 {TkpUseWindow procedure, container and embedded in same app} -constraints {
unix testembed
} -setup {
@@ -152,7 +227,7 @@ test unixEmbed-1.7 {TkpUseWindow procedure, container and embedded in same app}
test unixEmbed-2.1 {EmbeddedEventProc procedure} -constraints {
- unix testembed
+ unix testembed notAqua
} -setup {
deleteWindows
} -body {
@@ -172,8 +247,32 @@ test unixEmbed-2.1 {EmbeddedEventProc procedure} -constraints {
} -cleanup {
deleteWindows
} -result {}
+test unixEmbed-2.1a {EmbeddedEventProc procedure} -constraints {
+ unix testembed
+} -setup {
+ deleteWindows
+ catch {interp delete slave}
+ ::_test_tmp::testInterp slave
+ load {} Tktest slave
+} -body {
+ frame .f1 -container 1 -width 200 -height 50
+ pack .f1
+ slave alias w1 winfo id .f1
+ slave eval {
+ destroy [winfo child .]
+ toplevel .t1 -use [w1]
+ testembed
+ }
+ destroy .f1
+ update
+ slave eval {
+ testembed
+ }
+} -cleanup {
+ deleteWindows
+} -result {}
test unixEmbed-2.2 {EmbeddedEventProc procedure} -constraints {
- unix testembed
+ unix testembed notAqua
} -setup {
deleteWindows
} -body {
@@ -190,8 +289,30 @@ test unixEmbed-2.2 {EmbeddedEventProc procedure} -constraints {
} -cleanup {
deleteWindows
} -result {}
+test unixEmbed-2.2a {EmbeddedEventProc procedure} -constraints {
+ unix testembed
+} -setup {
+ deleteWindows
+ catch {interp delete slave}
+ ::_test_tmp::testInterp slave
+ load {} Tktest slave
+} -body {
+ frame .f1 -container 1 -width 200 -height 50
+ pack .f1
+ slave alias w1 winfo id .f1
+ slave eval {
+ destroy [winfo child .]
+ toplevel .t1 -use [w1]
+ testembed
+ destroy .t1
+ testembed
+ }
+} -cleanup {
+ interp delete slave
+ deleteWindows
+} -result {}
test unixEmbed-2.3 {EmbeddedEventProc procedure} -constraints {
- unix testembed
+ unix testembed notAqua
} -setup {
deleteWindows
} -body {
@@ -207,21 +328,20 @@ test unixEmbed-2.4 {EmbeddedEventProc procedure} -constraints {
} -setup {
deleteWindows
} -body {
- frame .f1 -container 1 -width 200 -height 50
- pack .f1
+ pack [frame .f1 -container 1 -width 200 -height 50]
toplevel .t1 -use [winfo id .f1]
+ set x [testembed]
update
destroy .t1
- set x [testembed]
update
- list $x [testembed]
+ list $x [winfo exists .t1] [winfo exists .f1] [testembed]
} -cleanup {
deleteWindows
-} -result {{{XXX .f1 {} {}}} {}}
+} -result "{{XXX .f1 {} .t1}} 0 0 {}"
test unixEmbed-3.1 {ContainerEventProc procedure, detect creation} -constraints {
- unix testembed nonPortable
+ unix testembed notPortable
} -body {
frame .f1 -container 1 -width 200 -height 50
pack .f1
@@ -236,10 +356,32 @@ test unixEmbed-3.1 {ContainerEventProc procedure, detect creation} -constraints
} -cleanup {
deleteWindows
} -result {{{XXX .f1 {} {}}} {{XXX .f1 XXX {}}}}
+test unixEmbed-3.1a {ContainerEventProc procedure, detect creation} -constraints {
+ unix testembed
+} -setup {
+ catch {interp delete slave}
+ ::_test_tmp::testInterp slave
+ load {} Tktest slave
+} -body {
+ frame .f1 -container 1 -width 200 -height 50
+ pack .f1
+ slave alias w1 winfo id .f1
+ set x [testembed]
+ slave eval {
+ destroy [winfo child .]
+ toplevel .t1 -use [w1]
+ wm withdraw .t1
+ }
+ list $x [testembed]
+} -cleanup {
+ interp delete slave
+ deleteWindows
+} -result {{{XXX .f1 {} {}}} {{XXX .f1 {} {}}}}
test unixEmbed-3.2 {ContainerEventProc procedure, set size on creation} -constraints {
unix
} -setup {
deleteWindows
+ update
} -body {
toplevel .t1 -container 1
wm geometry .t1 +0+0
@@ -250,7 +392,7 @@ test unixEmbed-3.2 {ContainerEventProc procedure, set size on creation} -constra
deleteWindows
} -result {200x200+0+0}
test unixEmbed-3.3 {ContainerEventProc procedure, disallow position changes} -constraints {
- unix
+ unix notAqua
} -setup {
deleteWindows
} -body {
@@ -270,8 +412,31 @@ test unixEmbed-3.3 {ContainerEventProc procedure, disallow position changes} -co
} -cleanup {
deleteWindows
} -result {200x200+0+0}
+test unixEmbed-3.3a {ContainerEventProc procedure, disallow position changes} -constraints {
+ unix
+} -setup {
+ deleteWindows
+ catch {interp delete slave}
+ ::_test_tmp::testInterp slave
+ load {} Tktest slave
+} -body {
+ frame .f1 -container 1 -width 200 -height 50
+ pack .f1
+ slave alias w1 winfo id .f1
+ slave eval {
+ destroy [winfo child .]
+ toplevel .t1 -use [w1] -bd 2 -relief raised
+ update
+ wm geometry .t1 +30+40
+ update
+ wm geometry .t1
+ }
+} -cleanup {
+ interp delete slave
+ deleteWindows
+} -result {200x200+0+0}
test unixEmbed-3.4 {ContainerEventProc procedure, disallow position changes} -constraints {
- unix
+ unix notAqua
} -setup {
deleteWindows
} -body {
@@ -291,8 +456,31 @@ test unixEmbed-3.4 {ContainerEventProc procedure, disallow position changes} -co
} -cleanup {
deleteWindows
} -result {300x100+0+0}
+test unixEmbed-3.4a {ContainerEventProc procedure, disallow position changes} -constraints {
+ unix
+} -setup {
+ deleteWindows
+ catch {interp delete slave}
+ ::_test_tmp::testInterp slave
+ load {} Tktest slave
+} -body {
+ frame .f1 -container 1 -width 200 -height 50
+ pack .f1
+ slave alias w1 winfo id .f1
+ slave eval {
+ destroy [winfo child .]
+ toplevel .t1 -use [w1]
+ update
+ wm geometry .t1 300x100+30+40
+ update
+ wm geometry .t1
+ }
+} -cleanup {
+ interp delete slave
+ deleteWindows
+} -result {300x100+0+0}
test unixEmbed-3.5 {ContainerEventProc procedure, geometry requests} -constraints {
- unix
+ unix notAqua
} -setup {
deleteWindows
} -body {
@@ -312,8 +500,30 @@ test unixEmbed-3.5 {ContainerEventProc procedure, geometry requests} -constraint
} -cleanup {
deleteWindows
} -result {300 80 300x80+0+0}
+test unixEmbed-3.5a {ContainerEventProc procedure, geometry requests} -constraints {
+ unix
+} -setup {
+ deleteWindows
+ catch {interp delete slave}
+ ::_test_tmp::testInterp slave
+ load {} Tktest slave
+} -body {
+ frame .f1 -container 1 -width 200 -height 50
+ pack .f1
+ slave alias w1 winfo id .f1
+ slave eval {
+ destroy [winfo child .]
+ toplevel .t1 -use [w1]
+ .t1 configure -width 300 -height 80
+ update
+ }
+ list [winfo width .f1] [winfo height .f1] [slave eval {wm geometry .t1}]
+} -cleanup {
+ interp delete slave
+ deleteWindows
+} -result {300 80 300x80+0+0}
test unixEmbed-3.6 {ContainerEventProc procedure, map requests} -constraints {
- unix
+ unix notAqua
} -setup {
deleteWindows
} -body {
@@ -335,8 +545,33 @@ test unixEmbed-3.6 {ContainerEventProc procedure, map requests} -constraints {
} -cleanup {
deleteWindows
} -result {mapped}
+test unixEmbed-3.6a {ContainerEventProc procedure, map requests} -constraints {
+ unix
+} -setup {
+ deleteWindows
+ catch {interp delete slave}
+ ::_test_tmp::testInterp slave
+ load {} Tktest slave
+} -body {
+ frame .f1 -container 1 -width 200 -height 50
+ pack .f1
+ slave alias w1 winfo id .f1
+ slave eval {
+ destroy [winfo child .]
+ toplevel .t1 -use [w1]
+ set x unmapped
+ bind .t1 <Map> {set x mapped}
+ update
+ after 100
+ update
+ set x
+ }
+} -cleanup {
+ interp delete slave
+ deleteWindows
+} -result {mapped}
test unixEmbed-3.7 {ContainerEventProc procedure, destroy events} -constraints {
- unix
+ unix notAqua
} -setup {
deleteWindows
} -body {
@@ -358,10 +593,34 @@ test unixEmbed-3.7 {ContainerEventProc procedure, destroy events} -constraints {
} -cleanup {
deleteWindows
} -result {dead 0}
-
+test unixEmbed-3.7a {ContainerEventProc procedure, destroy events} -constraints {
+ unix
+} -setup {
+ deleteWindows
+ catch {interp delete slave}
+ ::_test_tmp::testInterp slave
+ load {} Tktest slave
+} -body {
+ frame .f1 -container 1 -width 200 -height 50
+ pack .f1
+ slave alias w1 winfo id .f1
+ bind .f1 <Destroy> {set x dead}
+ set x alive
+ slave eval {
+ destroy [winfo child .]
+ toplevel .t1 -use [w1]
+ update
+ destroy .t1
+ }
+ update
+ list $x [winfo exists .f1]
+} -cleanup {
+ interp delete slave
+ deleteWindows
+} -result {dead 0}
test unixEmbed-4.1 {EmbedStructureProc procedure, configure events} -constraints {
- unix
+ unix notAqua
} -setup {
deleteWindows
} -body {
@@ -383,8 +642,31 @@ test unixEmbed-4.1 {EmbedStructureProc procedure, configure events} -constraints
} -cleanup {
deleteWindows
} -result {180x100+0+0}
+test unixEmbed-4.1a {EmbedStructureProc procedure, configure events} -constraints {
+ unix
+} -setup {
+ deleteWindows
+ catch {interp delete slave}
+ ::_test_tmp::testInterp slave
+ load {} Tktest slave
+} -body {
+ frame .f1 -container 1 -width 200 -height 50
+ pack .f1
+ slave alias w1 winfo id .f1
+ slave eval {
+ destroy [winfo child .]
+ toplevel .t1 -use [w1]
+ update
+ .t1 configure -width 180 -height 100
+ update
+ winfo geometry .t1
+ }
+} -cleanup {
+ interp delete slave
+ deleteWindows
+} -result {180x100+0+0}
test unixEmbed-4.2 {EmbedStructureProc procedure, destroy events} -constraints {
- unix testembed
+ unix testembed notAqua
} -setup {
deleteWindows
} -body {
@@ -398,14 +680,38 @@ test unixEmbed-4.2 {EmbedStructureProc procedure, destroy events} -constraints {
update
set x [testembed]
destroy .f1
+ update
list $x [testembed]
} -cleanup {
deleteWindows
} -result {{{XXX .f1 XXX {}}} {}}
+test unixEmbed-4.2a {EmbedStructureProc procedure, destroy events} -constraints {
+ unix testembed
+} -setup {
+ deleteWindows
+ catch {interp delete slave}
+ ::_test_tmp::testInterp slave
+ load {} Tktest slave
+} -body {
+ frame .f1 -container 1 -width 200 -height 50
+ pack .f1
+ update
+ slave alias w1 winfo id .f1
+ slave eval {
+ destroy [winfo child .]
+ toplevel .t1 -use [w1]
+ }
+ set x [testembed]
+ destroy .f1
+ list $x [testembed]
+} -cleanup {
+ interp delete slave
+ deleteWindows
+} -result "{{XXX .f1 {} {}}} {}"
test unixEmbed-5.1 {EmbedFocusProc procedure, FocusIn events} -constraints {
- unix
+ unix notAqua
} -setup {
deleteWindows
} -body {
@@ -425,8 +731,34 @@ test unixEmbed-5.1 {EmbedFocusProc procedure, FocusIn events} -constraints {
} -cleanup {
deleteWindows
} -result {{focus in .t1}}
+test unixEmbed-5.1a {EmbedFocusProc procedure, FocusIn events} -constraints {
+ unix
+} -setup {
+ deleteWindows
+ catch {interp delete slave}
+ ::_test_tmp::testInterp slave
+ load {} Tktest slave
+} -body {
+ frame .f1 -container 1 -width 200 -height 50
+ pack .f1
+ slave alias w1 winfo id .f1
+ slave eval {
+ destroy [winfo child .]
+ toplevel .t1 -use [w1]
+ bind .t1 <FocusIn> {lappend x "focus in %W"}
+ bind .t1 <FocusOut> {lappend x "focus out %W"}
+ update
+ set x {}
+ }
+ focus -force .f1
+ update
+ slave eval {set x}
+} -cleanup {
+ interp delete slave
+ deleteWindows
+} -result {{focus in .t1}}
test unixEmbed-5.2 {EmbedFocusProc procedure, focusing on dead window} -constraints {
- unix
+ unix notAqua
} -setup {
deleteWindows
} -body {
@@ -447,8 +779,32 @@ test unixEmbed-5.2 {EmbedFocusProc procedure, focusing on dead window} -constrai
} -cleanup {
deleteWindows
} -result {}
+test unixEmbed-5.2a {EmbedFocusProc procedure, focusing on dead window} -constraints {
+ unix
+} -setup {
+ deleteWindows
+ catch {interp delete slave}
+ ::_test_tmp::testInterp slave
+ load {} Tktest slave
+} -body {
+ frame .f1 -container 1 -width 200 -height 50
+ pack .f1
+ slave alias w1 winfo id .f1
+ slave eval {
+ destroy [winfo child .]
+ toplevel .t1 -use [w1]
+ update
+ after 200 {destroy .t1}
+ }
+ after 400
+ focus -force .f1
+ update
+} -cleanup {
+ interp delete slave
+ deleteWindows
+} -result {}
test unixEmbed-5.3 {EmbedFocusProc procedure, FocusOut events} -constraints {
- unix
+ unix notAqua
} -setup {
deleteWindows
} -body {
@@ -471,10 +827,39 @@ test unixEmbed-5.3 {EmbedFocusProc procedure, FocusOut events} -constraints {
} -cleanup {
deleteWindows
} -result {{{focus in .t1}} {{focus in .t1} {focus out .t1}}}
+test unixEmbed-5.3a {EmbedFocusProc procedure, FocusOut events} -constraints {
+ unix
+} -setup {
+ deleteWindows
+ catch {interp delete slave}
+ ::_test_tmp::testInterp slave
+ load {} Tktest slave
+} -body {
+ frame .f1 -container 1 -width 200 -height 50
+ pack .f1
+ slave alias w1 winfo id .f1
+ slave eval {
+ destroy [winfo child .]
+ toplevel .t1 -use [w1]
+ set x {}
+ bind .t1 <FocusIn> {lappend x "focus in %W"}
+ bind .t1 <FocusOut> {lappend x "focus out %W"}
+ update
+ }
+ focus -force .f1
+ update
+ set x [slave eval {update; set x }]
+ focus .
+ update
+ list $x [slave eval {update; set x}]
+} -cleanup {
+ interp delete slave
+ deleteWindows
+} -result {{{focus in .t1}} {{focus in .t1} {focus out .t1}}}
test unixEmbed-6.1 {EmbedGeometryRequest procedure, window changes size} -constraints {
- unix
+ unix notAqua
} -setup {
deleteWindows
} -body {
@@ -484,9 +869,7 @@ test unixEmbed-6.1 {EmbedGeometryRequest procedure, window changes size} -constr
dobg {
eval destroy [winfo child .]
toplevel .t1 -use $w1
- }
- update
- dobg {
+ update
bind .t1 <Configure> {lappend x {configure .t1 %w %h}}
set x {}
.t1 configure -width 300 -height 120
@@ -496,8 +879,33 @@ test unixEmbed-6.1 {EmbedGeometryRequest procedure, window changes size} -constr
} -cleanup {
deleteWindows
} -result {{{configure .t1 300 120}} 300x120+0+0}
+test unixEmbed-6.1a {EmbedGeometryRequest procedure, window changes size} -constraints {
+ unix
+} -setup {
+ deleteWindows
+ catch {interp delete slave}
+ ::_test_tmp::testInterp slave
+ load {} Tktest slave
+} -body {
+ frame .f1 -container 1 -width 200 -height 50
+ pack .f1
+ slave alias w1 winfo id .f1
+ slave eval {
+ destroy [winfo child .]
+ toplevel .t1 -use [w1]
+ update
+ bind .t1 <Configure> {set x {configure .t1 %w %h}}
+ set x {}
+ .t1 configure -width 300 -height 120
+ update
+ list $x [winfo geom .t1]
+ }
+} -cleanup {
+ interp delete slave
+ deleteWindows
+} -result {{configure .t1 300 120} 300x120+0+0}
test unixEmbed-6.2 {EmbedGeometryRequest procedure, window changes size} -constraints {
- unix
+ unix notAqua
} -setup {
deleteWindows
} -body {
@@ -507,25 +915,47 @@ test unixEmbed-6.2 {EmbedGeometryRequest procedure, window changes size} -constr
dobg {
eval destroy [winfo child .]
toplevel .t1 -use $w1
- }
- after 300 {set x done}
- vwait x
- dobg {
+ update
bind .t1 <Configure> {lappend x {configure .t1 %w %h}}
set x {}
.t1 configure -width 300 -height 120
- update
+ update
list $x [winfo geom .t1]
}
} -cleanup {
deleteWindows
} -result {{{configure .t1 200 200}} 200x200+0+0}
+test unixEmbed-6.2a {EmbedGeometryRequest procedure, window changes size} -constraints {
+ unix
+} -setup {
+ deleteWindows
+ catch {interp delete slave}
+ ::_test_tmp::testInterp slave
+ load {} Tktest slave
+} -body {
+ frame .f1 -container 1 -width 200 -height 50
+ place .f1 -width 200 -height 200
+ update
+ slave alias w1 winfo id .f1
+ slave eval {
+ destroy [winfo child .]
+ toplevel .t1 -use [w1]
+ update
+ bind .t1 <Configure> {set x {configure .t1 %w %h}}
+ set x {}
+ .t1 configure -width 300 -height 120
+ update
+ list $x [winfo geom .t1]
+ }
+} -cleanup {
+ interp delete slave
+ deleteWindows
+} -result {{configure .t1 200 200} 200x200+0+0}
# Can't think up any tests for TkpGetOtherWindow procedure.
-
test unixEmbed-7.1 {TkpRedirectKeyEvent procedure, forward keystroke} -constraints {
- unix
+ unix notAqua
} -setup {
deleteWindows
} -body {
@@ -553,8 +983,41 @@ test unixEmbed-7.1 {TkpRedirectKeyEvent procedure, forward keystroke} -constrain
deleteWindows
bind . <KeyPress> {}
} -result {{{key a 1}} {}}
+test unixEmbed-7.1a {TkpRedirectKeyEvent procedure, forward keystroke} -constraints {
+ unix
+} -setup {
+ deleteWindows
+ catch {interp delete slave}
+ ::_test_tmp::testInterp slave
+ load {} Tktest slave
+} -body {
+ deleteWindows
+ frame .f1 -container 1 -width 200 -height 50
+ pack .f1
+ slave alias w1 winfo id .f1
+ slave eval {
+ destroy [winfo child .]
+ toplevel .t1 -use [w1]
+ }
+ focus -force .
+ bind . <KeyPress> {lappend x {key %A %E}}
+ set x {}
+ set y [slave eval {
+ update
+ bind .t1 <KeyPress> {lappend y {key %A}}
+ set y {}
+ event generate .t1 <KeyPress> -keysym a
+ set y
+ }]
+ update
+ list $x $y
+} -cleanup {
+ interp delete slave
+ deleteWindows
+ bind . <KeyPress> {}
+} -result {{{key a 1}} {}}
test unixEmbed-7.2 {TkpRedirectKeyEvent procedure, don't forward keystroke width} -constraints {
- unix
+ unix notAqua
} -setup {
deleteWindows
} -body {
@@ -583,9 +1046,44 @@ test unixEmbed-7.2 {TkpRedirectKeyEvent procedure, don't forward keystroke width
deleteWindows
bind . <KeyPress> {}
} -result {{} {{key b}}}
+test unixEmbed-7.2a {TkpRedirectKeyEvent procedure, don't forward keystroke width} -constraints {
+ unix
+} -setup {
+ deleteWindows
+ catch {interp delete slave}
+ ::_test_tmp::testInterp slave
+ load {} Tktest slave
+} -body {
+ frame .f1 -container 1 -width 200 -height 50
+ pack .f1
+ slave alias w1 winfo id .f1
+ slave eval {
+ destroy [winfo child .]
+ toplevel .t1 -use [w1]
+ }
+ update
+ focus -force .f1
+ update
+ bind . <KeyPress> {lappend x {key %A}}
+ set x {}
+ set y [slave eval {
+ update
+ bind .t1 <KeyPress> {lappend y {key %A}}
+ set y {}
+ event generate .t1 <KeyPress> -keysym b
+ set y
+ }]
+ update
+ list $x $y
+} -cleanup {
+ interp delete slave
+ deleteWindows
+ bind . <KeyPress> {}
+} -result {{} {{key b}}}
-
-test unixEmbed-8.1 {TkpClaimFocus procedure} -constraints unix -setup {
+test unixEmbed-8.1 {TkpClaimFocus procedure} -constraints {
+ unix notAqua
+} -setup {
deleteWindows
} -body {
frame .f1 -container 1 -width 200 -height 50
@@ -609,15 +1107,44 @@ test unixEmbed-8.1 {TkpClaimFocus procedure} -constraints unix -setup {
} -cleanup {
deleteWindows
} -result {{{} .t1} .f1}
-test unixEmbed-8.2 {TkpClaimFocus procedure} -constraints unix -setup {
- deleteWindows
- catch {interp delete child}
+test unixEmbed-8.1a {TkpClaimFocus procedure} -constraints unix -setup {
deleteWindows
+ catch {interp delete slave}
+ ::_test_tmp::testInterp slave
+ load {} Tktest slave
} -body {
frame .f1 -container 1 -width 200 -height 50
frame .f2 -width 200 -height 50
pack .f1 .f2
+ update
+ slave alias w1 winfo id .f1
+ slave eval {
+ destroy [winfo child .]
+ toplevel .t1 -use [w1] -highlightthickness 2 -bd 2 -relief sunken
+ }
+ # This should clear focus from the application embedded in .f1
+ focus -force .f2
+ update
+ list [slave eval {
+ set x [list [focus]]
+ focus .t1
+ update
+ lappend x [focus]
+ }] [focus]
+} -cleanup {
+ interp delete slave
+ deleteWindows
+} -result {{{} .t1} .f1}
+test unixEmbed-8.2 {TkpClaimFocus procedure} -constraints unix -setup {
+ deleteWindows
+ catch {interp delete child}
interp create child
+} -body {
+ frame .f1 -container 1 -width 200 -height 50
+ frame .f2 -width 200 -height 50
+ pack .f1 .f2
+ update
+ set w1 [winfo id .f1]
child eval "set argv {-use [winfo id .f1]}"
load {} Tk child
child eval {
@@ -636,7 +1163,6 @@ test unixEmbed-8.2 {TkpClaimFocus procedure} -constraints unix -setup {
} -result {{{} .} .f1}
catch {interp delete child}
-
test unixEmbed-9.1 {EmbedWindowDeleted procedure, check parentPtr} -constraints {
unix testembed
} -setup {
@@ -658,12 +1184,13 @@ test unixEmbed-9.1 {EmbedWindowDeleted procedure, check parentPtr} -constraints
deleteWindows
} -result {{{XXX .f4 {} {}} {XXX .f3 {} {}} {XXX .f2 {} {}} {XXX .f1 {} {}}} {{XXX .f4 {} {}} {XXX .f2 {} {}} {XXX .f1 {} {}}} {{XXX .f2 {} {}} {XXX .f1 {} {}}} {{XXX .f2 {} {}}} {}}
test unixEmbed-9.2 {EmbedWindowDeleted procedure, check embeddedPtr} -constraints {
- unix testembed
+ unix testembed notAqua
} -setup {
deleteWindows
} -body {
frame .f1 -container 1 -width 200 -height 50
pack .f1
+ update
dobg "set w1 [winfo id .f1]"
dobg {
eval destroy [winfo child .]
@@ -676,6 +1203,29 @@ test unixEmbed-9.2 {EmbedWindowDeleted procedure, check embeddedPtr} -constraint
} -cleanup {
deleteWindows
} -result {{{XXX {} {} .t1}} {}}
+test unixEmbed-9.2a {EmbedWindowDeleted procedure, check embeddedPtr} -constraints {
+ unix testembed
+} -setup {
+ deleteWindows
+ catch {interp delete slave}
+ ::_test_tmp::testInterp slave
+ load {} Tktest slave
+} -body {
+ frame .f1 -container 1 -width 200 -height 50
+ pack .f1
+ slave alias w1 winfo id .f1
+ slave eval {
+ destroy [winfo child .]
+ toplevel .t1 -use [w1] -highlightthickness 2 -bd 2 -relief sunken
+ set x {}
+ lappend x [testembed]
+ destroy .t1
+ lappend x [testembed]
+ }
+} -cleanup {
+ interp delete slave
+ deleteWindows
+} -result {{{XXX {} {} .t1}} {}}
test unixEmbed-10.1 {geometry propagation in tkUnixWm.c/UpdateGeometryInfo} -constraints {
@@ -685,6 +1235,7 @@ test unixEmbed-10.1 {geometry propagation in tkUnixWm.c/UpdateGeometryInfo} -con
} -body {
frame .f1 -container 1 -width 200 -height 50
pack .f1
+ update
toplevel .t1 -use [winfo id .f1] -width 150 -height 80
update
wm geometry .t1 +40+50
@@ -714,4 +1265,3 @@ deleteWindows
cleanupbg
cleanupTests
return
-
diff --git a/tests/unixWm.test b/tests/unixWm.test
index 067327d..28c8159 100644
--- a/tests/unixWm.test
+++ b/tests/unixWm.test
@@ -40,8 +40,23 @@ proc makeToplevels {} {
}
}
+# On macOS windows are not allowed to overlap the menubar at the top
+# of the screen. So tests which move a window and then check whether
+# it got moved to the requested location should use a y coordinate
+# larger than the height of the menubar (normally 23 pixels).
+
+if {[tk windowingsystem] eq "aqua"} {
+ set Y0 23
+ set Y2 25
+ set Y5 28
+} else {
+ set Y0 0
+ set Y2 2
+ set Y5 5
+}
+
set i 1
-foreach geom {+20+80 +80+20 +0+0} {
+foreach geom "+23+80 +80+23 +0+$Y0" {
destroy .t
test unixWm-1.$i {initial window position} unix {
toplevel .t -width 200 -height 150
@@ -67,7 +82,7 @@ update
scan [wm geom .t] %dx%d+%d+%d width height x y
set xerr [expr 150-$x]
set yerr [expr 150-$y]
-foreach geom {+20+80 +80+20 +0+0 -0-0 +0-0 -0+0 -10-5 -10+5 +10-5} {
+foreach geom "+20+80 +80+23 +0+$Y0 -0-0 +0-0 -0+$Y0 -10-5 -10+$Y5 +10-5" {
test unixWm-2.$i {moving window while mapped} unix {
wm geom .t $geom
update
@@ -79,7 +94,7 @@ foreach geom {+20+80 +80+20 +0+0 -0-0 +0-0 -0+0 -10-5 -10+5 +10-5} {
}
set i 1
-foreach geom {+20+80 +80+20 +0+0 -0-0 +0-0 -0+0 -10-5 -10+5 +10-5} {
+foreach geom "+20+80 +80+23 +0+$Y0 -0-0 +0-0 -0+$Y0 -10-5 -10+$Y5 +10-5" {
test unixWm-3.$i {moving window while iconified} unix {
wm iconify .t
sleep 200
@@ -95,7 +110,7 @@ foreach geom {+20+80 +80+20 +0+0 -0-0 +0-0 -0+0 -10-5 -10+5 +10-5} {
}
set i 1
-foreach geom {+20+80 +100+40 +0+0} {
+foreach geom "+20+80 +100+40 +0+$Y0" {
test unixWm-4.$i {moving window while withdrawn} unix {
wm withdraw .t
sleep 200
@@ -179,27 +194,27 @@ test unixWm-5.7 {compounded state changes} {unix nonPortable} {
destroy .t
toplevel .t -width 200 -height 100
-wm geom .t +10+10
+wm geom .t +10+23
wm minsize .t 1 1
update
test unixWm-6.1 {size changes} unix {
.t config -width 180 -height 150
update
wm geom .t
-} 180x150+10+10
+} 180x150+10+23
test unixWm-6.2 {size changes} unix {
wm geom .t 250x60
.t config -width 170 -height 140
update
wm geom .t
-} 250x60+10+10
+} 250x60+10+23
test unixWm-6.3 {size changes} unix {
wm geom .t 250x60
.t config -width 170 -height 140
wm geom .t {}
update
wm geom .t
-} 170x140+10+10
+} 170x140+10+23
test unixWm-6.4 {size changes} {unix nonPortable userInteraction} {
wm minsize .t 1 1
update
@@ -808,14 +823,15 @@ test unixWm-22.2 {Tk_WmCmd procedure, "iconbitmap" option} {unix testwrapper} {
WM_HINTS] 0]]]
lappend result [wm iconbitmap .t] $bit
} {{} questhead 0x4 {} 0x0}
-test unixWm-22.3.1 {Tk_WmCmd procedure, "iconbitmap" option for unix only} \
-{unix notAqua} {
- list [catch {wm iconbitmap .t bad-bitmap} msg] $msg
-} {1 {bitmap "bad-bitmap" not defined}}
-test unixWm-22.3.2 {Tk_WmCmd procedure, "iconbitmap" option for Aqua only} \
-Aqua {
+if {[tk windowingsystem] == "aqua"} {
+ set result_22_3 {0 {}}
+} else {
+ set result_22_3 {1 {bitmap "bad-bitmap" not defined}}
+}
+test unixWm-22.3 {Tk_WmCmd procedure, "iconbitmap" option for unix only} \
+unix {
list [catch {wm iconbitmap .t bad-bitmap} msg] $msg
-} {1 {}}
+} $result_22_3
test unixWm-23.1 {Tk_WmCmd procedure, "iconify" option} unix {
list [catch {wm iconify .t 12} msg] $msg
@@ -1218,13 +1234,14 @@ test unixWm-34.2 {Tk_WmCmd procedure, "sizefrom" option} {unix testwrapper} {
test unixWm-34.3 {Tk_WmCmd procedure, "sizefrom" option} unix {
list [catch {wm sizefrom .t none} msg] $msg
} {1 {bad argument "none": must be program or user}}
-
-test unixWm-35.1.1 {Tk_WmCmd procedure, "state" option} {unix notAqua} {
- list [catch {wm state .t 1} msg] $msg
-} {1 {bad argument "1": must be normal, iconic, or withdrawn}}
-test unixWm-35.1.2 {Tk_WmCmd procedure, "state" option} Aqua {
+if {[tk windowingsystem] == "aqua"} {
+ set result_35_1 {1 {bad argument "1": must be normal, iconic, withdrawn, or zoomed}}
+} else {
+ set result_35_1 {1 {bad argument "1": must be normal, iconic, or withdrawn}}
+}
+test unixWm-35.1 {Tk_WmCmd procedure, "state" option} {unix notAqua} {
list [catch {wm state .t 1} msg] $msg
-} {1 {bad argument "1": must be normal, iconic, withdrawn, or zoomed}}
+} $result_35_1
test unixWm-35.2 {Tk_WmCmd procedure, "state" option} unix {
list [catch {wm state .t iconic 1} msg] $msg
} {1 {wrong # args: should be "wm state window ?state?"}}
@@ -1355,14 +1372,14 @@ test unixWm-40.1 {Tk_SetGrid procedure, set grid dimensions before turning on gr
test unixWm-40.2 {Tk_SetGrid procedure, turning on grid when dimensions already set} unix {
destroy .t
toplevel .t
- wm geometry .t 200x100+0+0
+ wm geometry .t 200x100+0+$Y0
listbox .t.l -height 20 -width 20
pack .t.l -fill both -expand 1
update
.t.l configure -setgrid 1
update
wm geometry .t
-} {20x20+0+0}
+} "20x20+0+$Y0"
test unixWm-41.1 {ConfigureEvent procedure, internally generated size changes} unix {
destroy .t
@@ -1557,10 +1574,10 @@ test unixWm-44.8 {UpdateGeometryInfo procedure, computing position} unix {
tkwait visibility .t
wm overrideredirect .t 1
update
- wm geometry .t -30+2
+ wm geometry .t -30+$Y2
update
list [winfo x .t] [winfo y .t]
-} [list [expr [winfo screenwidth .t] - 110] 2]
+} [list [expr [winfo screenwidth .t] - 110] $Y2]
destroy .t
test unixWm-44.9 {UpdateGeometryInfo procedure, updating fixed dimensions} {unix testwrapper} {
@@ -1777,88 +1794,103 @@ test unixWm-49.2 {Tk_GetRootCoords procedure, menubars} {unix testmenubar} {
} {52 7 12 62}
deleteWindows
-wm iconify .
-test unixWm-50.1 {Tk_CoordsToWindow procedure, finding a toplevel, x-coords} unix {
- deleteWindows
+wm withdraw .
+if {[tk windowingsystem] == "aqua"} {
+ # Modern mac windows have no border.
+ set result_50_1 {{} {} .t .t .t2 {} .t2 .t .t}
+} else {
+ # Windows are assumed to have a border (invisible in Gnome 3).
+ set result_50_1 {{} {} .t {} .t2 {} .t2 {} .t}
+}
+test unixWm-50.1 {Tk_CoordsToWindow procedure, finding a toplevel, x-coords, title bar} unix {
+ update
toplevel .t -width 300 -height 400 -bg green
- wm geom .t +40+0
+ wm geom .t +100+100
tkwait visibility .t
- toplevel .t2 -width 100 -height 80 -bg red
- wm geom .t2 +140+200
+ toplevel .t2 -width 100 -height 200 -bg red
+ wm geom .t2 +200+200
tkwait visibility .t2
raise .t2
+ update
set x [winfo rootx .t]
set y [winfo rooty .t]
- list [winfo containing [expr $x - 30] [expr $y + 250]] \
- [winfo containing [expr $x - 1] [expr $y + 250]] \
- [winfo containing $x [expr $y + 250]] \
- [winfo containing [expr $x + 99] [expr $y + 250]] \
- [winfo containing [expr $x + 100] [expr $y + 250]] \
- [winfo containing [expr $x + 199] [expr $y + 250]] \
- [winfo containing [expr $x + 200] [expr $y + 250]] \
- [winfo containing [expr $x + 220] [expr $y + 250]]
-} {{} {} .t {} .t2 .t2 {} .t}
+ list [winfo containing [expr $x - 30] [expr $y + 250]] \
+ [winfo containing [expr $x - 1] [expr $y + 250]] \
+ [winfo containing $x [expr $y + 250]] \
+ [winfo containing [expr $x + 99] [expr $y + 250]] \
+ [winfo containing [expr $x + 100] [expr $y + 250]] \
+ [winfo containing [expr $x + 150] [expr $y + 90]] \
+ [winfo containing [expr $x + 199] [expr $y + 250]] \
+ [winfo containing [expr $x + 200] [expr $y + 250]] \
+ [winfo containing [expr $x + 220] [expr $y + 250]] \
+} $result_50_1
test unixWm-50.2 {Tk_CoordsToWindow procedure, finding a toplevel, y-coords and overrideredirect} unix {
deleteWindows
- toplevel .t -width 300 -height 400 -bg yellow
- wm geom .t +0+50
+ toplevel .t -width 400 -height 300 -bg yellow
+ wm geom .t +100+100
tkwait visibility .t
- toplevel .t2 -width 100 -height 80 -bg blue
+ toplevel .t2 -width 200 -height 100 -bg blue
wm overrideredirect .t2 1
- wm geom .t2 +100+200
+ wm geom .t2 +200+200
tkwait visibility .t2
raise .t2
set x [winfo rootx .t]
set y [winfo rooty .t]
set y2 [winfo rooty .t2]
- list [winfo containing [expr $x +150] 10] \
- [winfo containing [expr $x +150] [expr $y - 1]] \
- [winfo containing [expr $x +150] $y] \
- [winfo containing [expr $x +150] [expr $y2 - 1]] \
- [winfo containing [expr $x +150] $y2] \
- [winfo containing [expr $x +150] [expr $y2 + 79]] \
- [winfo containing [expr $x +150] [expr $y2 + 80]] \
- [winfo containing [expr $x +150] [expr $y + 450]]
+ list [winfo containing [expr $x +200] [expr $y - 30]] \
+ [winfo containing [expr $x +200] [expr $y - 1]] \
+ [winfo containing [expr $x +200] $y] \
+ [winfo containing [expr $x +200] [expr $y2 - 1]] \
+ [winfo containing [expr $x +200] $y2] \
+ [winfo containing [expr $x +200] [expr $y2 + 99]] \
+ [winfo containing [expr $x +200] [expr $y2 + 100]] \
+ [winfo containing [expr $x +200] [expr $y + 450]]
} {{} {} .t .t .t2 .t2 .t {}}
test unixWm-50.3 {
Tk_CoordsToWindow procedure, finding a toplevel with embedding
-} -constraints tempNotWin -setup {
+} tempNotWin {
deleteWindows
+ catch {interp delete slave}
+
toplevel .t -width 300 -height 400 -bg blue
- wm geom .t +0+50
- frame .t.f -container 1
+ wm geom .t +100+100
+ frame .t.f -container 1 -bg red
place .t.f -x 150 -y 50
tkwait visibility .t.f
- setupbg
-} -body {
- dobg "
+ update
+ interp create slave
+ load {} Tk slave
+ slave alias frameid winfo id .t.f
+ slave eval {
wm withdraw .
- toplevel .x -width 100 -height 80 -use [winfo id .t.f] -bg yellow
- tkwait visibility .x"
- set result [dobg {
- set x [winfo rootx .x]
- set y [winfo rooty .x]
- list [winfo containing [expr $x - 1] [expr $y + 50]] \
- [winfo containing $x [expr $y +50]]
- }]
+ toplevel .x -width 100 -height 80 -use [frameid] -bg yellow
+ tkwait visibility .x
+ update
+ set x [winfo rootx .x]
+ set y [winfo rooty .x]
+ }
+ set result [list [slave eval {winfo containing [expr $x - 1] [expr $y + 50]}] \
+ [slave eval {winfo containing $x [expr $y + 50]}]]
+ interp delete slave
set x [winfo rootx .t]
set y [winfo rooty .t]
lappend result [winfo containing [expr $x + 200] [expr $y + 49]] \
- [winfo containing [expr $x + 200] [expr $y +50]]
-} -cleanup {
- cleanupbg
-} -result {{} .x .t .t.f}
+ [winfo containing [expr $x + 200] [expr $y +50]]
+ set result
+} {{} .x .t .t.f}
test unixWm-50.4 {Tk_CoordsToWindow procedure, window in other application} unix {
destroy .t
+
catch {interp delete slave}
toplevel .t -width 200 -height 200 -bg green
- wm geometry .t +0+0
+ wm geometry .t +100+100
tkwait visibility .t
+ update
interp create slave
load {} Tk slave
- slave eval {wm geometry . 200x200+0+0; tkwait visibility .}
- set result [list [winfo containing 100 100] \
- [slave eval {winfo containing 100 100}]]
+ slave eval {wm geometry . 200x200+100+100; tkwait visibility . ; update}
+ set result [list [winfo containing 200 200] \
+ [slave eval {winfo containing 200 200}]]
interp delete slave
set result
} {{} .}
@@ -1876,13 +1908,13 @@ test unixWm-50.5 {Tk_CoordsToWindow procedure, handling menubars} {unix testmenu
update
set x [winfo rootx .t]
set y [winfo rooty .t]
- list [winfo containing $x [expr $y - 31]] \
- [winfo containing $x [expr $y - 30]] \
- [winfo containing [expr $x + 50] [expr $y - 19]] \
- [winfo containing [expr $x + 50] [expr $y - 18]] \
- [winfo containing [expr $x + 50] $y] \
- [winfo containing [expr $x + 11] [expr $y + 152]] \
- [winfo containing [expr $x + 12] [expr $y + 152]]
+ list [winfo containing $x [expr $y - 31]] \
+ [winfo containing $x [expr $y - 30]] \
+ [winfo containing [expr $x + 50] [expr $y - 19]] \
+ [winfo containing [expr $x + 50] [expr $y - 18]] \
+ [winfo containing [expr $x + 50] $y] \
+ [winfo containing [expr $x + 11] [expr $y + 152]] \
+ [winfo containing [expr $x + 12] [expr $y + 152]]
} {{} .t.menu .t.menu .t.menu.f .t .t .t.f}
test unixWm-50.6 {Tk_CoordsToWindow procedure, embedding within one app.} unix {
deleteWindows
@@ -1947,6 +1979,7 @@ test unixWm-50.9 {Tk_CoordsToWindow procedure, unmapped windows} unix {
tkwait visibility .t2
set result [list [winfo containing 100 100]]
wm iconify .t2
+ animationDelay
lappend result [winfo containing 100 100]
} {.t2 .t}
test unixWm-50.10 {Tk_CoordsToWindow procedure, unmapped windows} unix {
@@ -2032,6 +2065,7 @@ test unixWm-51.6 {TkWmRestackToplevel procedure, window to be stacked isn't mapp
test unixWm-51.7 {TkWmRestackToplevel procedure, other window isn't mapped} unix {
foreach w {.t .t2 .t3} {
destroy $w
+ update
toplevel $w -width 200 -height 200 -bg green
wm geometry $w +0+0
}
@@ -2068,13 +2102,19 @@ test unixWm-51.8 {TkWmRestackToplevel procedure, overrideredirect windows} unix
raise .t2
lappend result [winfo containing $x $y]
} {.t2 .t .t2}
+# The mac won't put an overrideredirect window above the root,
+if {[tk windowingsystem] == "aqua"} {
+ wm withdraw .
+}
test unixWm-51.9 {TkWmRestackToplevel procedure, other window overrideredirect} unix {
foreach w {.t .t2 .t3} {
destroy $w
+ update
toplevel $w -width 200 -height 200 -bg green
wm overrideredirect $w 1
wm geometry $w +0+0
tkwait visibility $w
+ update
}
lower .t3 .t2
update
@@ -2090,6 +2130,9 @@ test unixWm-51.9 {TkWmRestackToplevel procedure, other window overrideredirect}
lower .t2
lappend result [winfo containing $x $y]
} {.t2 .t3}
+if {[tk windowingsystem] == "aqua"} {
+ wm deiconify .
+}
test unixWm-51.10 {TkWmRestackToplevel procedure, don't move window that's already in the right place} unix {
makeToplevels
raise .raise1
@@ -2465,11 +2508,18 @@ test unixWm-59.3 {exit processing} unix {
# NOTE: since [wm attributes] is not guaranteed to have any effect,
# the only thing we can really test here is the syntax.
#
+if {[tk windowingsystem] == "aqua"} {
+ set result_60_1 {-alpha 1.0 -fullscreen 0 -modified 0 -notify 0\
+ -titlepath {} -topmost 0 -transparent 0\
+ -type unsupported}
+} else {
+ set result_60_1 {-alpha 1.0 -topmost 0 -zoomed 0 -fullscreen 0 -type {}}
+}
test unixWm-60.1 {wm attributes - test} -constraints unix -body {
destroy .t
toplevel .t
wm attributes .t
-} -result [list -alpha 1.0 -topmost 0 -zoomed 0 -fullscreen 0 -type {}]
+} -result $result_60_1
test unixWm-60.2 {wm attributes - test} -constraints unix -body {
destroy .t
diff --git a/tests/wm.test b/tests/wm.test
index f56eaa7..df8d325 100644
--- a/tests/wm.test
+++ b/tests/wm.test
@@ -140,7 +140,7 @@ test wm-attributes-1.2.4 {usage} -constraints {unix notAqua} -returnCodes error
} -result {bad attribute "_": must be -alpha, -topmost, -zoomed, -fullscreen, or -type}
test wm-attributes-1.2.5 {usage} -constraints aqua -returnCodes error -body {
wm attributes . _
-} -result {bad attribute "_": must be -alpha, -fullscreen, -modified, -notify, -titlepath, -topmost, or -transparent}
+} -result {bad attribute "_": must be -alpha, -fullscreen, -modified, -notify, -titlepath, -topmost, -transparent, or -type}
### wm client ###
@@ -1519,7 +1519,7 @@ test wm-stackorder-5.1 {a menu is not a toplevel} -body {
test wm-stackorder-5.2 {A normal toplevel can't be raised above an \
overrideredirect toplevel on unix} -constraints x11 -body {
toplevel .t
- tkwait visibility .t
+ tkwait visibility .t
wm overrideredirect .t 1
raise .
update
@@ -1531,7 +1531,7 @@ test wm-stackorder-5.2 {A normal toplevel can't be raised above an \
test wm-stackorder-5.2.1 {A normal toplevel can be raised above an \
overrideredirect toplevel on macOS or win} -constraints aquaOrWin32 -body {
toplevel .t
- tkwait visibility .t
+ tkwait visibility .t
wm overrideredirect .t 1
raise .
update
@@ -1543,7 +1543,7 @@ test wm-stackorder-5.2.1 {A normal toplevel can be raised above an \
test wm-stackorder-5.3 {An overrideredirect window\
can be explicitly lowered} -body {
toplevel .t
- tkwait visibility .t
+ tkwait visibility .t
wm overrideredirect .t 1
lower .t
update
@@ -1640,14 +1640,24 @@ test wm-transient-1.7 {usage} -returnCodes error -body {
wm transient .master .master
} -cleanup {
deleteWindows
-} -result {can't make ".master" its own master}
+} -result {setting ".master" as master creates a transient/master cycle}
test wm-transient-1.8 {usage} -returnCodes error -body {
+ toplevel .t1
+ toplevel .t2
+ toplevel .t3
+ wm transient .t2 .t1
+ wm transient .t3 .t2
+ wm transient .t1 .t3
+} -cleanup {
+ deleteWindows
+} -result {setting ".t3" as master creates a transient/master cycle}
+test wm-transient-1.9 {usage} -returnCodes error -body {
toplevel .master
frame .master.f
wm transient .master .master.f
} -cleanup {
deleteWindows
-} -result {can't make ".master" its own master}
+} -result {setting ".master" as master creates a transient/master cycle}
test wm-transient-2.1 {basic get/set of master} -setup {
set results [list]
diff --git a/unix/tkUnix3d.c b/unix/tkUnix3d.c
index 038d4e1..2969de1 100644
--- a/unix/tkUnix3d.c
+++ b/unix/tkUnix3d.c
@@ -48,7 +48,7 @@ TkpGetBorder(void)
{
UnixBorder *borderPtr = ckalloc(sizeof(UnixBorder));
- borderPtr->solidGC = None;
+ borderPtr->solidGC = NULL;
return (TkBorder *) borderPtr;
}
@@ -76,7 +76,7 @@ TkpFreeBorder(
UnixBorder *unixBorderPtr = (UnixBorder *) borderPtr;
Display *display = DisplayOfScreen(borderPtr->screen);
- if (unixBorderPtr->solidGC != None) {
+ if (unixBorderPtr->solidGC != NULL) {
Tk_FreeGC(display, unixBorderPtr->solidGC);
}
}
@@ -124,7 +124,7 @@ Tk_3DVerticalBevel(
GC left, right;
Display *display = Tk_Display(tkwin);
- if ((borderPtr->lightGC == None) && (relief != TK_RELIEF_FLAT)) {
+ if ((borderPtr->lightGC == NULL) && (relief != TK_RELIEF_FLAT)) {
TkpGetShadows(borderPtr, tkwin);
}
@@ -159,7 +159,7 @@ Tk_3DVerticalBevel(
(unsigned) width, (unsigned) height);
} else if (relief == TK_RELIEF_SOLID) {
UnixBorder *unixBorderPtr = (UnixBorder *) borderPtr;
- if (unixBorderPtr->solidGC == None) {
+ if (unixBorderPtr->solidGC == NULL) {
XGCValues gcValues;
gcValues.foreground = BlackPixelOfScreen(borderPtr->screen);
@@ -216,11 +216,11 @@ Tk_3DHorizontalBevel(
Display *display = Tk_Display(tkwin);
int bottom, halfway, x1, x2, x1Delta, x2Delta;
UnixBorder *unixBorderPtr = (UnixBorder *) borderPtr;
- GC topGC = None, bottomGC = None;
+ GC topGC = NULL, bottomGC = NULL;
/* Initializations needed only to prevent
* compiler warnings. */
- if ((borderPtr->lightGC == None) && (relief != TK_RELIEF_FLAT) &&
+ if ((borderPtr->lightGC == NULL) && (relief != TK_RELIEF_FLAT) &&
(relief != TK_RELIEF_SOLID)) {
TkpGetShadows(borderPtr, tkwin);
}
@@ -246,7 +246,7 @@ Tk_3DHorizontalBevel(
bottomGC = borderPtr->darkGC;
break;
case TK_RELIEF_SOLID:
- if (unixBorderPtr->solidGC == None) {
+ if (unixBorderPtr->solidGC == NULL) {
XGCValues gcValues;
gcValues.foreground = BlackPixelOfScreen(borderPtr->screen);
@@ -344,7 +344,7 @@ TkpGetShadows(
int r, g, b;
XGCValues gcValues;
- if (borderPtr->lightGC != None) {
+ if (borderPtr->lightGC != NULL) {
return;
}
stressed = TkpCmapStressed(tkwin, borderPtr->colormap);
diff --git a/unix/tkUnixDefault.h b/unix/tkUnixDefault.h
index a5bcf4d..bc7cd93 100644
--- a/unix/tkUnixDefault.h
+++ b/unix/tkUnixDefault.h
@@ -246,7 +246,7 @@
#define DEF_MENU_ENTRY_ACTIVE_FG NULL
#define DEF_MENU_ENTRY_ACCELERATOR NULL
#define DEF_MENU_ENTRY_BG NULL
-#define DEF_MENU_ENTRY_BITMAP None
+#define DEF_MENU_ENTRY_BITMAP NULL
#define DEF_MENU_ENTRY_COLUMN_BREAK "0"
#define DEF_MENU_ENTRY_COMMAND NULL
#define DEF_MENU_ENTRY_COMPOUND "none"
diff --git a/unix/tkUnixEmbed.c b/unix/tkUnixEmbed.c
index 3cb5d26..2ac3013 100644
--- a/unix/tkUnixEmbed.c
+++ b/unix/tkUnixEmbed.c
@@ -503,7 +503,15 @@ EmbedStructureProc(
Tk_ErrorHandler errHandler;
if (eventPtr->type == ConfigureNotify) {
+ /*
+ * Send a ConfigureNotify to the embedded application.
+ */
+
+ if (containerPtr->embeddedPtr != None) {
+ TkDoConfigureNotify(containerPtr->embeddedPtr);
+ }
if (containerPtr->wrapper != None) {
+
/*
* Ignore errors, since the embedded application could have
* deleted its window.
@@ -873,6 +881,7 @@ TkpTestembedCmd(
Container *containerPtr;
Tcl_DString dString;
char buffer[50];
+ Tcl_Interp *embeddedInterp = NULL, *parentInterp = NULL;
ThreadSpecificData *tsdPtr =
Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
@@ -884,7 +893,17 @@ TkpTestembedCmd(
Tcl_DStringInit(&dString);
for (containerPtr = tsdPtr->firstContainerPtr; containerPtr != NULL;
containerPtr = containerPtr->nextPtr) {
+ if (containerPtr->embeddedPtr != NULL) {
+ embeddedInterp = containerPtr->embeddedPtr->mainPtr->interp;
+ }
+ if (containerPtr->parentPtr != NULL) {
+ parentInterp = containerPtr->parentPtr->mainPtr->interp;
+ }
+ if (embeddedInterp != interp && parentInterp != interp) {
+ continue;
+ }
Tcl_DStringStartSublist(&dString);
+ /* Parent id */
if (containerPtr->parent == None) {
Tcl_DStringAppendElement(&dString, "");
} else if (all) {
@@ -893,12 +912,15 @@ TkpTestembedCmd(
} else {
Tcl_DStringAppendElement(&dString, "XXX");
}
- if (containerPtr->parentPtr == NULL) {
+ /* Parent pathName */
+ if (containerPtr->parentPtr == NULL ||
+ parentInterp != interp) {
Tcl_DStringAppendElement(&dString, "");
} else {
Tcl_DStringAppendElement(&dString,
containerPtr->parentPtr->pathName);
}
+ /* Wrapper */
if (containerPtr->wrapper == None) {
Tcl_DStringAppendElement(&dString, "");
} else if (all) {
@@ -907,7 +929,9 @@ TkpTestembedCmd(
} else {
Tcl_DStringAppendElement(&dString, "XXX");
}
- if (containerPtr->embeddedPtr == NULL) {
+ /* Embedded window pathName */
+ if (containerPtr->embeddedPtr == NULL ||
+ embeddedInterp != interp) {
Tcl_DStringAppendElement(&dString, "");
} else {
Tcl_DStringAppendElement(&dString,
diff --git a/unix/tkUnixMenu.c b/unix/tkUnixMenu.c
index 2703412..d62cd50 100644
--- a/unix/tkUnixMenu.c
+++ b/unix/tkUnixMenu.c
@@ -888,7 +888,10 @@ DrawMenuUnderline(
*
* TkpPostMenu --
*
- * Posts a menu on the screen
+ * Posts a menu on the screen so that the top left corner of the
+ * specified entry is located at the point (x, y) in screen coordinates.
+ * If the entry parameter is negative, the upper left corner of the
+ * menu itself is placed at the point.
*
* Results:
* None.
@@ -903,9 +906,104 @@ int
TkpPostMenu(
Tcl_Interp *interp,
TkMenu *menuPtr,
- int x, int y)
+ int x, int y, int index)
{
- return TkPostTearoffMenu(interp, menuPtr, x, y);
+ return TkpPostTearoffMenu(interp, menuPtr, x, y, index);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkpPostTearoffMenu --
+ *
+ * Posts a tearoff menu on the screen so that the top left corner of the
+ * specified entry is located at the point (x, y) in screen coordinates.
+ * If the index parameter is negative, the upper left corner of the menu
+ * itself is placed at the point. On unix this is called when posting
+ * any menu. Adjusts the menu's position so that it fits on the screen,
+ * and maps and raises the menu.
+ *
+ * Results:
+ * Returns a standard Tcl Error.
+ *
+ * Side effects:
+ * The menu is posted.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TkpPostTearoffMenu(
+ Tcl_Interp *interp, /* The interpreter of the menu */
+ TkMenu *menuPtr, /* The menu we are posting */
+ int x, int y, int index) /* The root X,Y coordinates where the
+ * specified entry will be posted */
+{
+ int vRootX, vRootY, vRootWidth, vRootHeight;
+ int result;
+
+ if (index >= menuPtr->numEntries) {
+ index = menuPtr->numEntries - 1;
+ }
+ if (index >= 0) {
+ y -= menuPtr->entries[index]->y;
+ }
+
+ TkActivateMenuEntry(menuPtr, -1);
+ TkRecomputeMenu(menuPtr);
+ result = TkPostCommand(menuPtr);
+ if (result != TCL_OK) {
+ return result;
+ }
+
+ /*
+ * The post commands could have deleted the menu, which means we are dead
+ * and should go away.
+ */
+
+ if (menuPtr->tkwin == NULL) {
+ return TCL_OK;
+ }
+
+ /*
+ * Adjust the position of the menu if necessary to keep it visible on the
+ * screen. There are two special tricks to make this work right:
+ *
+ * 1. If a virtual root window manager is being used then the coordinates
+ * are in the virtual root window of menuPtr's parent; since the menu
+ * uses override-redirect mode it will be in the *real* root window for
+ * the screen, so we have to map the coordinates from the virtual root
+ * (if any) to the real root. Can't get the virtual root from the menu
+ * itself (it will never be seen by the wm) so use its parent instead
+ * (it would be better to have an an option that names a window to use
+ * for this...).
+ * 2. The menu may not have been mapped yet, so its current size might be
+ * the default 1x1. To compute how much space it needs, use its
+ * requested size, not its actual size.
+ */
+
+ Tk_GetVRootGeometry(Tk_Parent(menuPtr->tkwin), &vRootX, &vRootY,
+ &vRootWidth, &vRootHeight);
+ vRootWidth -= Tk_ReqWidth(menuPtr->tkwin);
+ if (x > vRootX + vRootWidth) {
+ x = vRootX + vRootWidth;
+ }
+ if (x < vRootX) {
+ x = vRootX;
+ }
+ vRootHeight -= Tk_ReqHeight(menuPtr->tkwin);
+ if (y > vRootY + vRootHeight) {
+ y = vRootY + vRootHeight;
+ }
+ if (y < vRootY) {
+ y = vRootY;
+ }
+ Tk_MoveToplevelWindow(menuPtr->tkwin, x, y);
+ if (!Tk_IsMapped(menuPtr->tkwin)) {
+ Tk_MapWindow(menuPtr->tkwin);
+ }
+ TkWmRestackToplevel((TkWindow *) menuPtr->tkwin, Above, NULL);
+ return TCL_OK;
}
/*
@@ -1720,7 +1818,6 @@ TkpComputeStandardMenuGeometry(
}
windowWidth = x + indicatorSpace + labelWidth + accelWidth
+ 2 * activeBorderWidth + borderWidth;
-
windowHeight += borderWidth;
/*
diff --git a/unix/tkUnixMenubu.c b/unix/tkUnixMenubu.c
index ba78016..c49f15b 100644
--- a/unix/tkUnixMenubu.c
+++ b/unix/tkUnixMenubu.c
@@ -92,7 +92,7 @@ TkpDisplayMenuButton(
border = mbPtr->normalBorder;
}
- if (mbPtr->image != None) {
+ if (mbPtr->image != NULL) {
Tk_SizeOfImage(mbPtr->image, &width, &height);
haveImage = 1;
} else if (mbPtr->bitmap != None) {
@@ -358,7 +358,7 @@ TkpComputeMenuButtonGeometry(
txtHeight = 0;
avgWidth = 0;
- if (mbPtr->image != None) {
+ if (mbPtr->image != NULL) {
Tk_SizeOfImage(mbPtr->image, &width, &height);
haveImage = 1;
} else if (mbPtr->bitmap != None) {
diff --git a/unix/tkUnixRFont.c b/unix/tkUnixRFont.c
index fd5c73c..9c15369 100644
--- a/unix/tkUnixRFont.c
+++ b/unix/tkUnixRFont.c
@@ -937,7 +937,7 @@ Tk_DrawChars(
doUnderlineStrikeout:
if (tsdPtr->clipRegion != None) {
- XftDrawSetClip(fontPtr->ftDraw, None);
+ XftDrawSetClip(fontPtr->ftDraw, NULL);
}
if (fontPtr->font.fa.underline != 0) {
XFillRectangle(display, drawable, gc, xStart,
@@ -1183,7 +1183,7 @@ TkDrawAngledChars(
doUnderlineStrikeout:
if (tsdPtr->clipRegion != None) {
- XftDrawSetClip(fontPtr->ftDraw, None);
+ XftDrawSetClip(fontPtr->ftDraw, NULL);
}
if (fontPtr->font.fa.underline || fontPtr->font.fa.overstrike) {
XPoint points[5];
diff --git a/unix/tkUnixScale.c b/unix/tkUnixScale.c
index d0208b7..8427cfe 100644
--- a/unix/tkUnixScale.c
+++ b/unix/tkUnixScale.c
@@ -150,11 +150,11 @@ DisplayVerticalScale(
for (tickValue = scalePtr->fromValue; ;
tickValue += tickInterval) {
/*
- * The TkRoundToResolution call gets rid of accumulated
+ * The TkRoundValueToResolution call gets rid of accumulated
* round-off errors, if any.
*/
- tickValue = TkRoundToResolution(scalePtr, tickValue);
+ tickValue = TkRoundValueToResolution(scalePtr, tickValue);
if (scalePtr->toValue >= scalePtr->fromValue) {
if (tickValue > scalePtr->toValue) {
break;
@@ -370,11 +370,11 @@ DisplayHorizontalScale(
for (tickValue = scalePtr->fromValue; ;
tickValue += tickInterval) {
/*
- * The TkRoundToResolution call gets rid of accumulated
+ * The TkRoundValueToResolution call gets rid of accumulated
* round-off errors, if any.
*/
- tickValue = TkRoundToResolution(scalePtr, tickValue);
+ tickValue = TkRoundValueToResolution(scalePtr, tickValue);
if (scalePtr->toValue >= scalePtr->fromValue) {
if (tickValue > scalePtr->toValue) {
break;
diff --git a/unix/tkUnixScrlbr.c b/unix/tkUnixScrlbr.c
index 5a7b0a1..d3e4436 100644
--- a/unix/tkUnixScrlbr.c
+++ b/unix/tkUnixScrlbr.c
@@ -65,8 +65,8 @@ TkpCreateScrollbar(
{
UnixScrollbar *scrollPtr = ckalloc(sizeof(UnixScrollbar));
- scrollPtr->troughGC = None;
- scrollPtr->copyGC = None;
+ scrollPtr->troughGC = NULL;
+ scrollPtr->copyGC = NULL;
Tk_CreateEventHandler(tkwin,
ExposureMask|StructureNotifyMask|FocusChangeMask,
@@ -366,10 +366,10 @@ TkpDestroyScrollbar(
{
UnixScrollbar *unixScrollPtr = (UnixScrollbar *)scrollPtr;
- if (unixScrollPtr->troughGC != None) {
+ if (unixScrollPtr->troughGC != NULL) {
Tk_FreeGC(scrollPtr->display, unixScrollPtr->troughGC);
}
- if (unixScrollPtr->copyGC != None) {
+ if (unixScrollPtr->copyGC != NULL) {
Tk_FreeGC(scrollPtr->display, unixScrollPtr->copyGC);
}
}
@@ -406,11 +406,11 @@ TkpConfigureScrollbar(
gcValues.foreground = scrollPtr->troughColorPtr->pixel;
new = Tk_GetGC(scrollPtr->tkwin, GCForeground, &gcValues);
- if (unixScrollPtr->troughGC != None) {
+ if (unixScrollPtr->troughGC != NULL) {
Tk_FreeGC(scrollPtr->display, unixScrollPtr->troughGC);
}
unixScrollPtr->troughGC = new;
- if (unixScrollPtr->copyGC == None) {
+ if (unixScrollPtr->copyGC == NULL) {
gcValues.graphics_exposures = False;
unixScrollPtr->copyGC = Tk_GetGC(scrollPtr->tkwin,
GCGraphicsExposures, &gcValues);
diff --git a/unix/tkUnixWm.c b/unix/tkUnixWm.c
index 1c55f40..f548bcd 100644
--- a/unix/tkUnixWm.c
+++ b/unix/tkUnixWm.c
@@ -3520,7 +3520,7 @@ WmTransientCmd(
Tcl_Obj *const objv[]) /* Argument objects. */
{
register WmInfo *wmPtr = winPtr->wmInfoPtr;
- TkWindow *masterPtr = wmPtr->masterPtr;
+ TkWindow *masterPtr = wmPtr->masterPtr, *w;
WmInfo *wmPtr2;
if ((objc != 3) && (objc != 4)) {
@@ -3589,12 +3589,18 @@ WmTransientCmd(
return TCL_ERROR;
}
- if (masterPtr == winPtr) {
- Tcl_SetObjResult(interp, Tcl_ObjPrintf(
- "can't make \"%s\" its own master", Tk_PathName(winPtr)));
- Tcl_SetErrorCode(interp, "TK", "WM", "TRANSIENT", "SELF", NULL);
- return TCL_ERROR;
- } else if (masterPtr != wmPtr->masterPtr) {
+ for (w = masterPtr; w != NULL && w->wmInfoPtr != NULL;
+ w = (TkWindow *)w->wmInfoPtr->masterPtr) {
+ if (w == winPtr) {
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "setting \"%s\" as master creates a transient/master cycle",
+ Tk_PathName(masterPtr)));
+ Tcl_SetErrorCode(interp, "TK", "WM", "TRANSIENT", "SELF", NULL);
+ return TCL_ERROR;
+ }
+ }
+
+ if (masterPtr != wmPtr->masterPtr) {
/*
* Remove old master map/unmap binding before setting the new
* master. The event handler will ensure that transient states
@@ -5781,6 +5787,18 @@ Tk_GetRootCoords(
*----------------------------------------------------------------------
*/
+static int PointInWindow(
+ int x,
+ int y,
+ WmInfo *wmPtr)
+{
+ XWindowChanges changes = wmPtr->winPtr->changes;
+ return (x >= changes.x &&
+ x < changes.x + changes.width &&
+ y >= changes.y - wmPtr->menuHeight &&
+ y < changes.y + changes.height);
+}
+
Tk_Window
Tk_CoordsToWindow(
int rootX, int rootY, /* Coordinates of point in root window. If a
@@ -5851,13 +5869,38 @@ Tk_CoordsToWindow(
}
for (wmPtr = (WmInfo *) dispPtr->firstWmPtr; wmPtr != NULL;
wmPtr = wmPtr->nextPtr) {
- if (wmPtr->reparent == child) {
- goto gotToplevel;
+ if (wmPtr->winPtr->mainPtr == NULL) {
+ continue;
+ }
+ if (child == wmPtr->reparent) {
+ if (PointInWindow(x, y, wmPtr)) {
+ goto gotToplevel;
+ } else {
+
+ /*
+ * Return NULL if the point is in the title bar or border.
+ */
+
+ return NULL;
+ }
}
if (wmPtr->wrapperPtr != NULL) {
if (child == wmPtr->wrapperPtr->window) {
goto gotToplevel;
- }
+ } else if (wmPtr->winPtr->flags & TK_EMBEDDED &&
+ TkpGetOtherWindow(wmPtr->winPtr) == NULL) {
+
+ /*
+ * This toplevel is embedded in a window belonging to
+ * a different application.
+ */
+
+ int rx, ry;
+ Tk_GetRootCoords((Tk_Window) wmPtr->winPtr, &rx, &ry);
+ childX -= rx;
+ childY -= ry;
+ goto gotToplevel;
+ }
} else if (child == wmPtr->winPtr->window) {
goto gotToplevel;
}
@@ -5879,9 +5922,6 @@ Tk_CoordsToWindow(
handler = NULL;
}
winPtr = wmPtr->winPtr;
- if (winPtr->mainPtr != ((TkWindow *) tkwin)->mainPtr) {
- return NULL;
- }
/*
* Step 3: at this point winPtr and wmPtr refer to the toplevel that
@@ -5938,27 +5978,30 @@ Tk_CoordsToWindow(
if (nextPtr == NULL) {
break;
}
- winPtr = nextPtr;
- x -= winPtr->changes.x;
- y -= winPtr->changes.y;
- if ((winPtr->flags & TK_CONTAINER)
- && (winPtr->flags & TK_BOTH_HALVES)) {
+ x -= nextPtr->changes.x;
+ y -= nextPtr->changes.y;
+ if ((nextPtr->flags & TK_CONTAINER)
+ && (nextPtr->flags & TK_BOTH_HALVES)) {
/*
* The window containing the point is a container, and the
* embedded application is in this same process. Switch over to
* the toplevel for the embedded application and start processing
* that toplevel from scratch.
*/
-
- winPtr = TkpGetOtherWindow(winPtr);
+ winPtr = TkpGetOtherWindow(nextPtr);
if (winPtr == NULL) {
- return NULL;
+ return (Tk_Window) nextPtr;
}
wmPtr = winPtr->wmInfoPtr;
childX = x;
childY = y;
goto gotToplevel;
- }
+ } else {
+ winPtr = nextPtr;
+ }
+ }
+ if (winPtr->mainPtr != ((TkWindow *) tkwin)->mainPtr) {
+ return NULL;
}
return (Tk_Window) winPtr;
}
diff --git a/win/tkWin3d.c b/win/tkWin3d.c
index d3c443d..9f7ca22 100644
--- a/win/tkWin3d.c
+++ b/win/tkWin3d.c
@@ -127,7 +127,7 @@ Tk_3DVerticalBevel(
HDC dc = TkWinGetDrawableDC(display, drawable, &state);
int half;
- if ((borderPtr->lightGC == None) && (relief != TK_RELIEF_FLAT)) {
+ if ((borderPtr->lightGC == NULL) && (relief != TK_RELIEF_FLAT)) {
TkpGetShadows(borderPtr, tkwin);
}
@@ -222,7 +222,7 @@ Tk_3DHorizontalBevel(
HDC dc = TkWinGetDrawableDC(display, drawable, &state);
int topColor, bottomColor;
- if ((borderPtr->lightGC == None) && (relief != TK_RELIEF_FLAT)) {
+ if ((borderPtr->lightGC == NULL) && (relief != TK_RELIEF_FLAT)) {
TkpGetShadows(borderPtr, tkwin);
}
@@ -339,7 +339,7 @@ TkpGetShadows(
int r, g, b;
XGCValues gcValues;
- if (borderPtr->lightGC != None) {
+ if (borderPtr->lightGC != NULL) {
return;
}
@@ -540,7 +540,7 @@ TkWinGetBorderPixels(
{
WinBorder *borderPtr = (WinBorder *) border;
- if (borderPtr->info.lightGC == None) {
+ if (borderPtr->info.lightGC == NULL) {
TkpGetShadows(&borderPtr->info, tkwin);
}
switch (which) {
diff --git a/win/tkWinButton.c b/win/tkWinButton.c
index 9cd13a7..f4039cf 100644
--- a/win/tkWinButton.c
+++ b/win/tkWinButton.c
@@ -127,7 +127,7 @@ InitBoxes(void)
HRSRC hrsrc;
HGLOBAL hblk;
LPBITMAPINFOHEADER newBitmap;
- DWORD size;
+ size_t size;
ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
@@ -146,8 +146,9 @@ InitBoxes(void)
if (tsdPtr->boxesPtr != NULL && !(tsdPtr->boxesPtr->biWidth % 4)
&& !(tsdPtr->boxesPtr->biHeight % 2)) {
- size = tsdPtr->boxesPtr->biSize + (1 << tsdPtr->boxesPtr->biBitCount)
- * sizeof(RGBQUAD) + tsdPtr->boxesPtr->biSizeImage;
+ size = tsdPtr->boxesPtr->biSize
+ + (sizeof(RGBQUAD) << tsdPtr->boxesPtr->biBitCount)
+ + tsdPtr->boxesPtr->biSizeImage;
newBitmap = ckalloc(size);
memcpy(newBitmap, tsdPtr->boxesPtr, size);
tsdPtr->boxesPtr = newBitmap;
@@ -156,7 +157,7 @@ InitBoxes(void)
tsdPtr->boxesPalette = (DWORD*) (((LPSTR) tsdPtr->boxesPtr)
+ tsdPtr->boxesPtr->biSize);
tsdPtr->boxesBits = ((LPSTR) tsdPtr->boxesPalette)
- + ((1 << tsdPtr->boxesPtr->biBitCount) * sizeof(RGBQUAD));
+ + (sizeof(RGBQUAD) << tsdPtr->boxesPtr->biBitCount);
} else {
tsdPtr->boxesPtr = NULL;
}
@@ -433,7 +434,7 @@ TkpDisplayButton(
* Display image or bitmap or text for button.
*/
- if (butPtr->image != None) {
+ if (butPtr->image != NULL) {
Tk_SizeOfImage(butPtr->image, &width, &height);
haveImage = 1;
} else if (butPtr->bitmap != None) {
diff --git a/win/tkWinDefault.h b/win/tkWinDefault.h
index a1c8f88..194ee1f 100644
--- a/win/tkWinDefault.h
+++ b/win/tkWinDefault.h
@@ -249,7 +249,7 @@
#define DEF_MENU_ENTRY_ACTIVE_FG NULL
#define DEF_MENU_ENTRY_ACCELERATOR NULL
#define DEF_MENU_ENTRY_BG NULL
-#define DEF_MENU_ENTRY_BITMAP None
+#define DEF_MENU_ENTRY_BITMAP NULL
#define DEF_MENU_ENTRY_COLUMN_BREAK "0"
#define DEF_MENU_ENTRY_COMMAND NULL
#define DEF_MENU_ENTRY_COMPOUND "none"
diff --git a/win/tkWinDialog.c b/win/tkWinDialog.c
index 5a9034d..11b556a 100644
--- a/win/tkWinDialog.c
+++ b/win/tkWinDialog.c
@@ -3351,7 +3351,7 @@ FontchooserConfigureCmd(
Tk_Window parent = Tk_NameToWindow(interp,
Tcl_GetString(objv[i+1]), tkwin);
- if (parent == None) {
+ if (parent == NULL) {
return TCL_ERROR;
}
if (hdPtr->parentObj) {
@@ -3446,7 +3446,7 @@ FontchooserShowCmd(
if (hdPtr->parentObj) {
parent = Tk_NameToWindow(interp, Tcl_GetString(hdPtr->parentObj),
tkwin);
- if (parent == None) {
+ if (parent == NULL) {
return TCL_ERROR;
}
}
diff --git a/win/tkWinDraw.c b/win/tkWinDraw.c
index e13a5e5..7a6e7bc 100644
--- a/win/tkWinDraw.c
+++ b/win/tkWinDraw.c
@@ -519,6 +519,7 @@ TkPutImage(
BITMAPINFO *infoPtr;
HBITMAP bitmap;
char *data;
+ Visual *visual;
display->request++;
@@ -556,7 +557,7 @@ TkPutImage(
infoPtr = ckalloc(sizeof(BITMAPINFOHEADER)
+ sizeof(RGBQUAD)*ncolors);
} else {
- infoPtr = ckalloc(sizeof(BITMAPINFOHEADER));
+ infoPtr = ckalloc(sizeof(BITMAPINFOHEADER) + sizeof(DWORD)*4);
}
infoPtr->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
@@ -564,13 +565,13 @@ TkPutImage(
infoPtr->bmiHeader.biHeight = -image->height; /* Top-down order */
infoPtr->bmiHeader.biPlanes = 1;
infoPtr->bmiHeader.biBitCount = image->bits_per_pixel;
- infoPtr->bmiHeader.biCompression = BI_RGB;
infoPtr->bmiHeader.biSizeImage = 0;
infoPtr->bmiHeader.biXPelsPerMeter = 0;
infoPtr->bmiHeader.biYPelsPerMeter = 0;
infoPtr->bmiHeader.biClrImportant = 0;
if (usePalette) {
+ infoPtr->bmiHeader.biCompression = BI_RGB;
infoPtr->bmiHeader.biClrUsed = ncolors;
for (i = 0; i < ncolors; i++) {
infoPtr->bmiColors[i].rgbBlue = GetBValue(colors[i]);
@@ -579,7 +580,13 @@ TkPutImage(
infoPtr->bmiColors[i].rgbReserved = 0;
}
} else {
- infoPtr->bmiHeader.biClrUsed = 0;
+ infoPtr->bmiHeader.biCompression = BI_BITFIELDS;
+ /* Modelled on XGetVisualInfo() in xutil.c.
+ * We want to get the rgb masks for the default visual for the given display. */
+ visual = DefaultVisual(display,0);
+ *((DWORD *)((unsigned char *)infoPtr + sizeof(BITMAPINFOHEADER))) = visual->blue_mask;
+ *((DWORD *)((unsigned char *)infoPtr + sizeof(BITMAPINFOHEADER))+1) = visual->green_mask;
+ *((DWORD *)((unsigned char *)infoPtr + sizeof(BITMAPINFOHEADER))+2) = visual->red_mask;
}
bitmap = CreateDIBitmap(dc, &infoPtr->bmiHeader, CBM_INIT,
image->data, infoPtr, DIB_RGB_COLORS);
diff --git a/win/tkWinEmbed.c b/win/tkWinEmbed.c
index daffb94..c45f088 100644
--- a/win/tkWinEmbed.c
+++ b/win/tkWinEmbed.c
@@ -856,6 +856,15 @@ ContainerEventProc(
Tk_Window tkwin = (Tk_Window)containerPtr->parentPtr;
if (eventPtr->type == ConfigureNotify) {
+
+ /*
+ * Send a ConfigureNotify to the embedded application.
+ */
+
+ if (containerPtr->embeddedPtr != NULL) {
+ TkDoConfigureNotify(containerPtr->embeddedPtr);
+ }
+
/*
* Resize the embedded window, if there is any.
*/
diff --git a/win/tkWinFont.c b/win/tkWinFont.c
index aa0697c..4ffa32b 100644
--- a/win/tkWinFont.c
+++ b/win/tkWinFont.c
@@ -988,7 +988,7 @@ Tk_MeasureChars(
}
*lengthPtr = curX;
- return p - source;
+ return (int)(p - source);
}
/*
diff --git a/win/tkWinImage.c b/win/tkWinImage.c
index d61b84a..0a8ef73 100644
--- a/win/tkWinImage.c
+++ b/win/tkWinImage.c
@@ -347,7 +347,7 @@ XGetImageZPixmap(
size = sizeof(BITMAPINFO);
if (depth <= 8) {
- size += sizeof(unsigned short) * (1 << depth);
+ size += sizeof(unsigned short) << depth;
}
bmInfo = ckalloc(size);
diff --git a/win/tkWinMenu.c b/win/tkWinMenu.c
index 6ac14c2..1896474 100644
--- a/win/tkWinMenu.c
+++ b/win/tkWinMenu.c
@@ -743,7 +743,10 @@ ReconfigureWindowsMenu(
*
* TkpPostMenu --
*
- * Posts a menu on the screen
+ * Posts a menu on the screen so that the top left corner of the
+ * specified entry is located at the point (x, y) in screen coordinates.
+ * If the entry parameter is negative, the upper left corner of the
+ * menu itself is placed at the point.
*
* Results:
* None.
@@ -758,7 +761,7 @@ int
TkpPostMenu(
Tcl_Interp *interp,
TkMenu *menuPtr,
- int x, int y)
+ int x, int y, int index)
{
HMENU winMenuHdl = (HMENU) menuPtr->platformData;
int result, flags;
@@ -770,7 +773,6 @@ TkpPostMenu(
Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
tsdPtr->inPostMenu++;
-
CallPendingReconfigureImmediately(menuPtr);
result = TkPreprocessMenu(menuPtr);
@@ -779,6 +781,13 @@ TkpPostMenu(
return result;
}
+ if (index >= menuPtr->numEntries) {
+ index = menuPtr->numEntries - 1;
+ }
+ if (index >= 0) {
+ y -= menuPtr->entries[index]->y;
+ }
+
/*
* The post commands could have deleted the menu, which means
* we are dead and should go away.
@@ -841,6 +850,100 @@ TkpPostMenu(
/*
*----------------------------------------------------------------------
*
+ * TkpPostTearoffMenu --
+ *
+ * Posts a tearoff menu on the screen so that the top left corner of the
+ * specified entry is located at the point (x, y) in screen coordinates.
+ * If the index parameter is negative, the upper left corner of the menu
+ * itself is placed at the point. Adjusts the menu's position so that it
+ * fits on the screen, and maps and raises the menu.
+ *
+ * Results:
+ * Returns a standard Tcl Error.
+ *
+ * Side effects:
+ * The menu is posted.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TkpPostTearoffMenu(
+ Tcl_Interp *interp, /* The interpreter of the menu */
+ TkMenu *menuPtr, /* The menu we are posting */
+ int x, int y, int index) /* The root X,Y coordinates where we are
+ * posting */
+{
+ int vRootX, vRootY, vRootWidth, vRootHeight;
+ int result;
+
+ if (index >= menuPtr->numEntries) {
+ index = menuPtr->numEntries - 1;
+ }
+ if (index >= 0) {
+ y -= menuPtr->entries[index]->y;
+ }
+
+ TkActivateMenuEntry(menuPtr, -1);
+ TkRecomputeMenu(menuPtr);
+ result = TkPostCommand(menuPtr);
+ if (result != TCL_OK) {
+ return result;
+ }
+
+ /*
+ * The post commands could have deleted the menu, which means we are dead
+ * and should go away.
+ */
+
+ if (menuPtr->tkwin == NULL) {
+ return TCL_OK;
+ }
+
+ /*
+ * Adjust the position of the menu if necessary to keep it visible on the
+ * screen. There are two special tricks to make this work right:
+ *
+ * 1. If a virtual root window manager is being used then the coordinates
+ * are in the virtual root window of menuPtr's parent; since the menu
+ * uses override-redirect mode it will be in the *real* root window for
+ * the screen, so we have to map the coordinates from the virtual root
+ * (if any) to the real root. Can't get the virtual root from the menu
+ * itself (it will never be seen by the wm) so use its parent instead
+ * (it would be better to have an an option that names a window to use
+ * for this...).
+ * 2. The menu may not have been mapped yet, so its current size might be
+ * the default 1x1. To compute how much space it needs, use its
+ * requested size, not its actual size.
+ */
+
+ Tk_GetVRootGeometry(Tk_Parent(menuPtr->tkwin), &vRootX, &vRootY,
+ &vRootWidth, &vRootHeight);
+ vRootWidth -= Tk_ReqWidth(menuPtr->tkwin);
+ if (x > vRootX + vRootWidth) {
+ x = vRootX + vRootWidth;
+ }
+ if (x < vRootX) {
+ x = vRootX;
+ }
+ vRootHeight -= Tk_ReqHeight(menuPtr->tkwin);
+ if (y > vRootY + vRootHeight) {
+ y = vRootY + vRootHeight;
+ }
+ if (y < vRootY) {
+ y = vRootY;
+ }
+ Tk_MoveToplevelWindow(menuPtr->tkwin, x, y);
+ if (!Tk_IsMapped(menuPtr->tkwin)) {
+ Tk_MapWindow(menuPtr->tkwin);
+ }
+ TkWmRestackToplevel((TkWindow *) menuPtr->tkwin, Above, NULL);
+ return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
* TkpMenuNewEntry --
*
* Adds a pointer to a new menu entry structure with the platform-
@@ -2363,7 +2466,7 @@ DrawMenuEntryLabel(
XFillRectangle(menuPtr->display, d, menuPtr->disabledGC, x, y,
(unsigned) width, (unsigned) height);
} else if ((mePtr->image != NULL)
- && (menuPtr->disabledImageGC != None)) {
+ && (menuPtr->disabledImageGC != NULL)) {
XFillRectangle(menuPtr->display, d, menuPtr->disabledImageGC,
leftEdge + imageXOffset,
(int) (y + (mePtr->height - imageHeight)/2 + imageYOffset),
@@ -2912,7 +3015,6 @@ TkpComputeStandardMenuGeometry(
GetTearoffEntryGeometry(menuPtr, menuPtr->entries[i], tkfont,
fmPtr, &width, &height);
menuPtr->entries[i]->height = height;
-
} else {
/*
* For each entry, compute the height required by that particular
@@ -2970,8 +3072,6 @@ TkpComputeStandardMenuGeometry(
}
windowWidth = x + indicatorSpace + labelWidth + accelWidth
+ 2 * activeBorderWidth + borderWidth;
-
-
windowHeight += borderWidth;
/*
diff --git a/win/tkWinPort.h b/win/tkWinPort.h
index 11b60f3..254f44e 100644
--- a/win/tkWinPort.h
+++ b/win/tkWinPort.h
@@ -91,6 +91,10 @@
* See ticket [916c1095438eae56]: GetVersionExW triggers warnings
*/
#if defined(_MSC_VER)
+# pragma warning(disable:4267)
+# pragma warning(disable:4244)
+# pragma warning(disable:4311)
+# pragma warning(disable:4312)
# pragma warning(disable:4996)
#endif
diff --git a/win/tkWinWm.c b/win/tkWinWm.c
index 2e3a2a1..4d8a952 100644
--- a/win/tkWinWm.c
+++ b/win/tkWinWm.c
@@ -2625,7 +2625,7 @@ TkWmDeadWindow(
VisibilityChangeMask|StructureNotifyMask,
WmWaitVisibilityOrMapProc, wmPtr2->winPtr);
wmPtr2->masterPtr = NULL;
- if ((wmPtr2->wrapper != None)
+ if ((wmPtr2->wrapper != NULL)
&& !(wmPtr2->flags & (WM_NEVER_MAPPED))) {
UpdateWrapper(wmPtr2->winPtr);
}
@@ -5526,7 +5526,7 @@ WmTransientCmd(
Tcl_Obj *const objv[]) /* Argument objects. */
{
register WmInfo *wmPtr = winPtr->wmInfoPtr;
- TkWindow *masterPtr = wmPtr->masterPtr, **masterPtrPtr = &masterPtr;
+ TkWindow *masterPtr = wmPtr->masterPtr, **masterPtrPtr = &masterPtr, *w;
WmInfo *wmPtr2;
if ((objc != 3) && (objc != 4)) {
@@ -5584,13 +5584,17 @@ WmTransientCmd(
Tcl_SetErrorCode(interp, "TK", "WM", "TRANSIENT", "ICON", NULL);
return TCL_ERROR;
}
-
- if (masterPtr == winPtr) {
- Tcl_SetObjResult(interp, Tcl_ObjPrintf(
- "can't make \"%s\" its own master", Tk_PathName(winPtr)));
- Tcl_SetErrorCode(interp, "TK", "WM", "TRANSIENT", "SELF", NULL);
- return TCL_ERROR;
- } else if (masterPtr != wmPtr->masterPtr) {
+ for (w = masterPtr; w != NULL && w->wmInfoPtr != NULL;
+ w = (TkWindow *)w->wmInfoPtr->masterPtr) {
+ if (w == winPtr) {
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "setting \"%s\" as master creates a transient/master cycle",
+ Tk_PathName(masterPtr)));
+ Tcl_SetErrorCode(interp, "TK", "WM", "TRANSIENT", "SELF", NULL);
+ return TCL_ERROR;
+ }
+ }
+ if (masterPtr != wmPtr->masterPtr) {
/*
* Remove old master map/unmap binding before setting the new
* master. The event handler will ensure that transient states
@@ -8623,7 +8627,7 @@ TkpWinToplevelDetachWindow(
SendMessage(wmPtr->wrapper, TK_DETACHWINDOW, 0, 0);
winPtr->flags &= ~TK_EMBEDDED;
winPtr->privatePtr = NULL;
- wmPtr->wrapper = None;
+ wmPtr->wrapper = NULL;
if (state >= 0 && state <= 3) {
wmPtr->hints.initial_state = state;
}
diff --git a/win/tkWinX.c b/win/tkWinX.c
index f12b05c..34633a6 100644
--- a/win/tkWinX.c
+++ b/win/tkWinX.c
@@ -457,21 +457,21 @@ TkWinDisplayChanged(
} else if (screen->root_depth == 12) {
screen->root_visual->class = TrueColor;
screen->root_visual->map_entries = 32;
- screen->root_visual->red_mask = 0xf0;
+ screen->root_visual->red_mask = 0xf00000;
screen->root_visual->green_mask = 0xf000;
- screen->root_visual->blue_mask = 0xf00000;
+ screen->root_visual->blue_mask = 0xf0;
} else if (screen->root_depth == 16) {
screen->root_visual->class = TrueColor;
screen->root_visual->map_entries = 64;
- screen->root_visual->red_mask = 0xf8;
+ screen->root_visual->red_mask = 0xf80000;
screen->root_visual->green_mask = 0xfc00;
- screen->root_visual->blue_mask = 0xf80000;
+ screen->root_visual->blue_mask = 0xf8;
} else if (screen->root_depth >= 24) {
screen->root_visual->class = TrueColor;
screen->root_visual->map_entries = 256;
- screen->root_visual->red_mask = 0xff;
+ screen->root_visual->red_mask = 0xff0000;
screen->root_visual->green_mask = 0xff00;
- screen->root_visual->blue_mask = 0xff0000;
+ screen->root_visual->blue_mask = 0xff;
}
screen->root_visual->bits_per_rgb = screen->root_depth;
ReleaseDC(NULL, dc);
@@ -539,7 +539,7 @@ TkpOpenDisplay(
twdPtr = ckalloc(sizeof(TkWinDrawable));
if (twdPtr == NULL) {
- return None;
+ return NULL;
}
twdPtr->type = TWD_WINDOW;
twdPtr->window.winPtr = NULL;
diff --git a/xlib/X11/X.h b/xlib/X11/X.h
index daf2283..2a9cd52 100644
--- a/xlib/X11/X.h
+++ b/xlib/X11/X.h
@@ -73,7 +73,7 @@ typedef unsigned long KeyCode; /* In order to use IME, the Macintosh needs
* RESERVED RESOURCE AND CONSTANT DEFINITIONS
*****************************************************************/
-#define None 0L /* universal null resource or null atom */
+/* #define None 0L See bug [9e31fd9449] and below */
#define ParentRelative 1L /* background pixmap in CreateWindow
and ChangeWindowAttributes */
@@ -179,13 +179,16 @@ are reserved in the protocol for errors and replies. */
#define ShiftMask (1<<0)
#define LockMask (1<<1)
-#define ControlMask (1<<2)
+/* #define ControlMask (1<<2) See bug [9e31fd9449] and below */
#define Mod1Mask (1<<3)
#define Mod2Mask (1<<4)
#define Mod3Mask (1<<5)
#define Mod4Mask (1<<6)
#define Mod5Mask (1<<7)
+/* See bug [9e31fd9449], this way prevents conflicts with Win32 headers */
+enum _Bug9e31fd9449 { None = 0, ControlMask = (1<<2) };
+
/* modifier names. Used to build a SetModifierMapping request or
to read a GetModifierMapping request. These correspond to the
masks defined above. */
diff --git a/xlib/xgc.c b/xlib/xgc.c
index eea1ebb..a1308f9 100644
--- a/xlib/xgc.c
+++ b/xlib/xgc.c
@@ -50,7 +50,7 @@
static TkpClipMask *AllocClipMask(GC gc) {
TkpClipMask *clip_mask = (TkpClipMask*) gc->clip_mask;
- if (clip_mask == None) {
+ if (clip_mask == NULL) {
clip_mask = ckalloc(sizeof(TkpClipMask));
gc->clip_mask = (Pixmap) clip_mask;
#ifdef MAC_OSX_TK
@@ -125,7 +125,7 @@ XCreateGC(
gp = ckalloc(sizeof(XGCValues) + MAX_DASH_LIST_SIZE + gcCacheSize);
if (!gp) {
- return None;
+ return NULL;
}
#define InitField(name,maskbit,default) \
@@ -268,7 +268,7 @@ int XFreeGC(
Display *d,
GC gc)
{
- if (gc != None) {
+ if (gc != NULL) {
FreeClipMask(gc);
TkpFreeGCCache(gc);
ckfree(gc);
@@ -464,8 +464,8 @@ TkSetRegion(
GC gc,
TkRegion r)
{
- if (r == None) {
- Tcl_Panic("must not pass None to TkSetRegion for compatibility with X11; use XSetClipMask instead");
+ if (r == NULL) {
+ Tcl_Panic("must not pass NULL to TkSetRegion for compatibility with X11; use XSetClipMask instead");
} else {
TkpClipMask *clip_mask = AllocClipMask(gc);
diff --git a/xlib/xutil.c b/xlib/xutil.c
index c629b82..1e81549 100644
--- a/xlib/xutil.c
+++ b/xlib/xutil.c
@@ -10,9 +10,6 @@
*/
#include "tkInt.h"
-#include <X11/Xlib.h>
-#include <X11/Xutil.h>
-#include <X11/Xatom.h>
/*
*----------------------------------------------------------------------