summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/keysyms.n11
-rw-r--r--doc/ttk_notebook.n3
-rw-r--r--doc/ttk_panedwindow.n3
-rw-r--r--generic/ks_names.h19
-rw-r--r--generic/tkBind.c25
-rw-r--r--generic/tkTextBTree.c3
-rw-r--r--generic/ttk/ttkNotebook.c81
-rw-r--r--tests/color.test22
-rw-r--r--win/tkWinKey.c11
-rw-r--r--xlib/X11/keysymdef.h12
-rw-r--r--xlib/xcolors.c10
11 files changed, 156 insertions, 44 deletions
diff --git a/doc/keysyms.n b/doc/keysyms.n
index bf81440..512c1a6 100644
--- a/doc/keysyms.n
+++ b/doc/keysyms.n
@@ -15,7 +15,9 @@ Tk recognizes many keysyms when specifying key bindings (e.g.,
.QW "\fBbind\fR \fB. <Key-\fR\fIkeysym\fR\fB>\fR" ).
The following list enumerates the
keysyms that will be recognized by Tk. Note that not all keysyms will
-be valid on all platforms. For example, on Unix systems, the presence
+be valid on all platforms, and some keysyms are also available on
+platforms that have a different native name for that key.
+For example, on Unix systems, the presence
of a particular keysym is dependant on the configuration of the
keyboard modifier map. This list shows keysyms along with their
decimal and hexadecimal values.
@@ -918,6 +920,13 @@ Super_R 65516 0xffec
Hyper_L 65517 0xffed
Hyper_R 65518 0xffee
Delete 65535 0xffff
+XF86AudioLowerVolume 269025041 0x1008FF11
+XF86AudioMute 269025042 0x1008FF12
+XF86AudioRaiseVolume 269025043 0x1008FF13
+XF86AudioPlay 269025044 0x1008FF14
+XF86AudioStop 269025045 0x1008FF15
+XF86AudioPrev 269025046 0x1008FF16
+XF86AudioNext 269025047 0x1008FF17
.CE
.SH "SEE ALSO"
bind(n), event(n)
diff --git a/doc/ttk_notebook.n b/doc/ttk_notebook.n
index 4d1b789..290a0c7 100644
--- a/doc/ttk_notebook.n
+++ b/doc/ttk_notebook.n
@@ -171,7 +171,8 @@ Otherwise, sets the \fI\-option\fRs to the corresponding \fIvalue\fRs.
See \fBTAB OPTIONS\fR for the available options.
.TP
\fIpathname \fBtabs\fR
-Returns the list of windows managed by the notebook.
+Returns the list of windows managed by the notebook, in the index order of
+their associated tabs.
.SH "KEYBOARD TRAVERSAL"
To enable keyboard traversal for a toplevel window
containing a notebook widget \fI$nb\fR, call:
diff --git a/doc/ttk_panedwindow.n b/doc/ttk_panedwindow.n
index 29fca1d..4ba42bc 100644
--- a/doc/ttk_panedwindow.n
+++ b/doc/ttk_panedwindow.n
@@ -91,7 +91,8 @@ If one \fI\-option\fR is specified, returns the value of that \fIoption\fR.
Otherwise, sets the \fI\-option\fRs to the corresponding \fIvalue\fRs.
.TP
\fIpathname \fBpanes\fR
-Returns the list of all windows managed by the widget.
+Returns the list of all windows managed by the widget, in the index order of
+their associated panes.
.TP
\fIpathname \fBsashpos \fIindex\fR ?\fInewpos\fR?
If \fInewpos\fR is specified, sets the position
diff --git a/generic/ks_names.h b/generic/ks_names.h
index 22d9fc5..9f49130 100644
--- a/generic/ks_names.h
+++ b/generic/ks_names.h
@@ -1,5 +1,15 @@
/*
- * This file is generated from $(INCLUDESRC)/keysymdef.h. Do not edit.
+ * This file should be maintained in sync with xlib/X11/keysymdefs.h
+ *
+ * Note that this should be done manually only, because in some cases
+ * keysymdefs.h defines the same integer for multiple keysyms, e.g.:
+ *
+ * #define XK_Greek_LAMDA 0x7cb
+ * #define XK_Greek_LAMBDA 0x7cb
+ *
+ * #define XK_Cyrillic_DZHE 0x6bf
+ * #define XK_Serbian_DZE 0x6bf (deprecated)
+ *
*/
{ "BackSpace", 0xFF08 },
{ "Tab", 0xFF09 },
@@ -920,3 +930,10 @@
{ "hebrew_shin", 0xcf9 },
{ "hebrew_taf", 0xcfa },
{ "Hebrew_switch", 0xFF7E },
+{ "XF86AudioLowerVolume", 0x1008FF11 },
+{ "XF86AudioMute", 0x1008FF12 },
+{ "XF86AudioRaiseVolume", 0x1008FF13 },
+{ "XF86AudioPlay", 0x1008FF14 },
+{ "XF86AudioStop", 0x1008FF15 },
+{ "XF86AudioPrev", 0x1008FF16 },
+{ "XF86AudioNext", 0x1008FF17 },
diff --git a/generic/tkBind.c b/generic/tkBind.c
index 8a6fc56..aaa5386 100644
--- a/generic/tkBind.c
+++ b/generic/tkBind.c
@@ -3466,12 +3466,28 @@ HandleEventGenerate(
if ((warp != 0) && Tk_IsMapped(tkwin)) {
TkDisplay *dispPtr = TkGetDisplay(event.general.xmotion.display);
+ /*
+ * TODO: No protection is in place to handle dispPtr destruction
+ * before DoWarp is called back.
+ */
+
+ Tk_Window warpWindow = Tk_IdToWindow(dispPtr->display,
+ event.general.xmotion.window);
+
if (!(dispPtr->flags & TK_DISPLAY_IN_WARP)) {
Tcl_DoWhenIdle(DoWarp, dispPtr);
dispPtr->flags |= TK_DISPLAY_IN_WARP;
}
- dispPtr->warpWindow = Tk_IdToWindow(dispPtr->display,
- event.general.xmotion.window);
+
+ if (warpWindow != dispPtr->warpWindow) {
+ if (warpWindow) {
+ Tcl_Preserve(warpWindow);
+ }
+ if (dispPtr->warpWindow) {
+ Tcl_Release(dispPtr->warpWindow);
+ }
+ dispPtr->warpWindow = warpWindow;
+ }
dispPtr->warpMainwin = mainWin;
dispPtr->warpX = event.general.xmotion.x;
dispPtr->warpY = event.general.xmotion.y;
@@ -3559,6 +3575,11 @@ DoWarp(
TkpWarpPointer(dispPtr);
XForceScreenSaver(dispPtr->display, ScreenSaverReset);
}
+
+ if (dispPtr->warpWindow) {
+ Tcl_Release(dispPtr->warpWindow);
+ dispPtr->warpWindow = None;
+ }
dispPtr->flags &= ~TK_DISPLAY_IN_WARP;
}
diff --git a/generic/tkTextBTree.c b/generic/tkTextBTree.c
index 0fdc280..db0d71a 100644
--- a/generic/tkTextBTree.c
+++ b/generic/tkTextBTree.c
@@ -1439,6 +1439,7 @@ TkBTreeDeleteIndexRange(
prevNodePtr->nextPtr = curNodePtr->nextPtr;
}
parentPtr->numChildren--;
+ ckfree(curNodePtr->numPixels);
ckfree(curNodePtr);
curNodePtr = parentPtr;
}
@@ -4185,6 +4186,7 @@ Rebalance(
treePtr->rootPtr = nodePtr->children.nodePtr;
treePtr->rootPtr->parentPtr = NULL;
DeleteSummaries(nodePtr->summaryPtr);
+ ckfree(nodePtr->numPixels);
ckfree(nodePtr);
}
return;
@@ -4274,6 +4276,7 @@ Rebalance(
nodePtr->nextPtr = otherPtr->nextPtr;
nodePtr->parentPtr->numChildren--;
DeleteSummaries(otherPtr->summaryPtr);
+ ckfree(otherPtr->numPixels);
ckfree(otherPtr);
continue;
}
diff --git a/generic/ttk/ttkNotebook.c b/generic/ttk/ttkNotebook.c
index 81a8b64..06aa275 100644
--- a/generic/ttk/ttkNotebook.c
+++ b/generic/ttk/ttkNotebook.c
@@ -4,6 +4,7 @@
#include <string.h>
#include <ctype.h>
+#include <math.h>
#include <stdio.h>
#include <tk.h>
@@ -288,13 +289,14 @@ static void ActivateTab(Notebook *nb, int index)
* TabState --
* Return the state of the specified tab, based on
* notebook state, currentIndex, activeIndex, and user-specified tab state.
- * The USER1 bit is set for the leftmost tab, and USER2
- * is set for the rightmost tab.
+ * The USER1 bit is set for the leftmost visible tab, and USER2
+ * is set for the rightmost visible tab.
*/
static Ttk_State TabState(Notebook *nb, int index)
{
Ttk_State state = nb->core.state;
Tab *tab = Ttk_SlaveData(nb->notebook.mgr, index);
+ int i = 0;
if (index == nb->notebook.currentIndex) {
state |= TTK_STATE_SELECTED;
@@ -305,11 +307,25 @@ static Ttk_State TabState(Notebook *nb, int index)
if (index == nb->notebook.activeIndex) {
state |= TTK_STATE_ACTIVE;
}
- if (index == 0) {
- state |= TTK_STATE_USER1;
+ for (i = 0; i < Ttk_NumberSlaves(nb->notebook.mgr); ++i) {
+ Tab *tab = Ttk_SlaveData(nb->notebook.mgr, i);
+ if (tab->state == TAB_STATE_HIDDEN) {
+ continue;
+ }
+ if (index == i) {
+ state |= TTK_STATE_USER1;
+ }
+ break;
}
- if (index == Ttk_NumberSlaves(nb->notebook.mgr) - 1) {
- state |= TTK_STATE_USER2;
+ for (i = Ttk_NumberSlaves(nb->notebook.mgr) - 1; i >= 0; --i) {
+ Tab *tab = Ttk_SlaveData(nb->notebook.mgr, i);
+ if (tab->state == TAB_STATE_HIDDEN) {
+ continue;
+ }
+ if (index == i) {
+ state |= TTK_STATE_USER2;
+ }
+ break;
}
if (tab->state == TAB_STATE_DISABLED) {
state |= TTK_STATE_DISABLED;
@@ -325,6 +341,8 @@ static Ttk_State TabState(Notebook *nb, int index)
/* TabrowSize --
* Compute max height and total width of all tabs (horizontal layouts)
* or total height and max width (vertical layouts).
+ * The -mintabwidth style option is taken into account (for the width
+ * only).
*
* Side effects:
* Sets width and height fields for all tabs.
@@ -334,7 +352,7 @@ static Ttk_State TabState(Notebook *nb, int index)
* (max height/width) but not parallel (total width/height).
*/
static void TabrowSize(
- Notebook *nb, Ttk_Orient orient, int *widthPtr, int *heightPtr)
+ Notebook *nb, Ttk_Orient orient, int minTabWidth, int *widthPtr, int *heightPtr)
{
Ttk_Layout tabLayout = nb->notebook.tabLayout;
int tabrowWidth = 0, tabrowHeight = 0;
@@ -346,6 +364,7 @@ static void TabrowSize(
Ttk_RebindSublayout(tabLayout, tab);
Ttk_LayoutSize(tabLayout,tabState,&tab->width,&tab->height);
+ tab->width = MAX(tab->width, minTabWidth);
if (orient == TTK_ORIENT_HORIZONTAL) {
tabrowHeight = MAX(tabrowHeight, tab->height);
@@ -406,7 +425,7 @@ static int NotebookSize(void *clientData, int *widthPtr, int *heightPtr)
/* Tab row:
*/
- TabrowSize(nb, nbstyle.tabOrient, &tabrowWidth, &tabrowHeight);
+ TabrowSize(nb, nbstyle.tabOrient, nbstyle.minTabWidth, &tabrowWidth, &tabrowHeight);
tabrowHeight += Ttk_PaddingHeight(nbstyle.tabMargins);
tabrowWidth += Ttk_PaddingWidth(nbstyle.tabMargins);
@@ -436,47 +455,32 @@ static int NotebookSize(void *clientData, int *widthPtr, int *heightPtr)
/* SqueezeTabs --
* Squeeze or stretch tabs to fit within the tab area parcel.
+ * This happens independently of the -mintabwidth style option.
*
- * All tabs are adjusted by an equal amount, but will not be made
- * smaller than the minimum width. (If all the tabs still do
- * not fit in the available space, the rightmost ones will
- * be further squozen by PlaceTabs()).
- *
- * The algorithm does not always yield an optimal layout, but does
- * have the important property that decreasing the available width
- * by one pixel will cause at most one tab to shrink by one pixel;
- * this means that tabs resize "smoothly" when the window shrinks
- * and grows.
+ * All tabs are adjusted by an equal amount.
*
* @@@ <<NOTE-TABPOSITION>> bug: only works for horizontal orientations
* @@@ <<NOTE-SQUEEZE-HIDDEN>> does not account for hidden tabs.
*/
static void SqueezeTabs(
- Notebook *nb, int needed, int available, int minTabWidth)
+ Notebook *nb, int needed, int available)
{
int nTabs = Ttk_NumberSlaves(nb->notebook.mgr);
if (nTabs > 0) {
- int difference = available - needed,
- delta = difference / nTabs,
- remainder = difference % nTabs,
- slack = 0;
+ int difference = available - needed;
+ double fraction = (double)difference / needed;
+ double slack = 0;
+ double ad;
int i;
- if (remainder < 0) { remainder += nTabs; --delta; }
-
for (i = 0; i < nTabs; ++i) {
Tab *tab = Ttk_SlaveData(nb->notebook.mgr,i);
- int adj = delta + (i < remainder) + slack;
-
- if (tab->width + adj >= minTabWidth) {
- tab->width += adj;
- slack = 0;
- } else {
- slack = adj - (minTabWidth - tab->width);
- tab->width = minTabWidth;
- }
+
+ ad = slack + tab->width * fraction;
+ tab->width += (int)ad;
+ slack = ad - floor(ad);
}
}
}
@@ -539,8 +543,13 @@ static void NotebookDoLayout(void *recordPtr)
Ttk_PlaceLayout(nb->core.layout, nb->core.state, Ttk_WinBox(nbwin));
/* Place tabs:
+ * Note: TabrowSize() takes into account -mintabwidth, but the tabs will
+ * actually have this minimum size when displayed only if there is enough
+ * space to draw the tabs with this width. Otherwise some of the tabs can
+ * be squeezed to a size smaller than -mintabwidth because we prefer
+ * displaying all tabs than than honoring -mintabwidth for all of them.
*/
- TabrowSize(nb, nbstyle.tabOrient, &tabrowWidth, &tabrowHeight);
+ TabrowSize(nb, nbstyle.tabOrient, nbstyle.minTabWidth, &tabrowWidth, &tabrowHeight);
tabrowBox = Ttk_PadBox(
Ttk_PositionBox(&cavity,
tabrowWidth + Ttk_PaddingWidth(nbstyle.tabMargins),
@@ -548,7 +557,7 @@ static void NotebookDoLayout(void *recordPtr)
nbstyle.tabPosition),
nbstyle.tabMargins);
- SqueezeTabs(nb, tabrowWidth, tabrowBox.width, nbstyle.minTabWidth);
+ SqueezeTabs(nb, tabrowWidth, tabrowBox.width);
PlaceTabs(nb, tabrowBox, nbstyle.tabPlacement);
/* Layout for client area frame:
diff --git a/tests/color.test b/tests/color.test
index 0b328cf..4e7adfc 100644
--- a/tests/color.test
+++ b/tests/color.test
@@ -90,6 +90,16 @@ proc colorsFree {w {red 31} {green 245} {blue 192}} {
&& ([lindex $vals 2]/256 == $blue)
}
+# -- WARNING (SB, 6.4.2017) --
+#
+# The if block below looks _very_ outdated. It didn't get any
+# substatial changes as far back as the fossil history goes. It might
+# be from a time, when 256 color was the best you could get! :-o.
+#
+# The problem is, on machines with a fancy 24 truecolor display, the
+# 'colorsFree' constraint doesn't get set, turning off pretty much every test
+# in this file.
+
if {[testConstraint psuedocolor8]} {
toplevel .t -visual {pseudocolor 8} -colormap new
wm geom .t +0+0
@@ -185,6 +195,18 @@ test color-2.6 {Tk_GetColor procedure} {colorsFree nonPortable} {
test color-2.7 {Tk_GetColor procedure} colorsFree {
winfo rgb .t #ff0000
} {65535 0 0}
+test color-2.8 {Tk_GetColor, invalid char after 3 valid hex digits} -body {
+ winfo rgb . #abcg
+} -returnCodes error -result {invalid color name "#abcg"}
+test color-2.9 {Tk_GetColor, invalid char after 6 vaild hex digits} -body {
+ winfo rgb . #aabbccz
+} -returnCodes error -result {invalid color name "#aabbccz"}
+test color-2.10 {Tk_GetColor, 3 hex digits, last one invalid} -body {
+ winfo rgb . #abz
+} -returnCodes error -result {invalid color name "#abz"}
+test color-2.11 {Tk_GetColor, 6 hex digits, last one invalid} -body {
+ winfo rgb . #12345g
+} -returnCodes error -result {invalid color name "#12345g"}
test color-3.1 {Tk_FreeColor procedure, reference counting} colorsFree {
eval destroy [winfo child .t]
diff --git a/win/tkWinKey.c b/win/tkWinKey.c
index 1ebf312..357a804 100644
--- a/win/tkWinKey.c
+++ b/win/tkWinKey.c
@@ -21,7 +21,8 @@
* like a worthwhile improvement to use the table.
*/
-#define MAX_KEYCODE 145 /* VK_SCROLL is the last entry in our table below */
+#define MAX_KEYCODE 179 /* VK_MEDIA_PLAY_PAUSE is the last entry in our table below */
+/* cf. https://msdn.microsoft.com/en-us/library/windows/desktop/dd375731(v=vs.85).aspx */
static const KeySym keymap[] = {
NoSymbol, NoSymbol, NoSymbol, XK_Cancel, NoSymbol,
@@ -53,7 +54,13 @@ static const KeySym keymap[] = {
XK_F19, XK_F20, XK_F21, XK_F22, XK_F23,
XK_F24, NoSymbol, NoSymbol, NoSymbol, NoSymbol,
NoSymbol, NoSymbol, NoSymbol, NoSymbol, XK_Num_Lock,
- XK_Scroll_Lock
+ XK_Scroll_Lock, NoSymbol, NoSymbol, NoSymbol, NoSymbol,
+ NoSymbol, NoSymbol, NoSymbol, NoSymbol, NoSymbol, /*150 0x96*/
+ NoSymbol, NoSymbol, NoSymbol, NoSymbol, NoSymbol, /*155 0x9b*/
+ NoSymbol, NoSymbol, NoSymbol, NoSymbol, NoSymbol, /*160 0xa0*/
+ NoSymbol, NoSymbol, NoSymbol, NoSymbol, NoSymbol, /*165 0xa5*/
+ NoSymbol, NoSymbol, NoSymbol, XK_XF86AudioMute, XK_XF86AudioLowerVolume, /*170 0xaa*/
+ XK_XF86AudioRaiseVolume, XK_XF86AudioNext, XK_XF86AudioPrev, XK_XF86AudioStop, XK_XF86AudioPlay /*175 0xaf*/
};
/*
diff --git a/xlib/X11/keysymdef.h b/xlib/X11/keysymdef.h
index b22d41b..a7c654d 100644
--- a/xlib/X11/keysymdef.h
+++ b/xlib/X11/keysymdef.h
@@ -1167,3 +1167,15 @@ SOFTWARE.
#define XK_Hebrew_switch 0xFF7E /* Alias for mode_switch */
#endif /* XK_HEBREW */
+/* Multimedia keys, defined same as on Linux
+ * /usr/include/pkg/libxkbcommon/xkbcommon/xkbcommon-keysyms.h
+ */
+
+#define XK_XF86AudioLowerVolume 0x1008FF11 /* Volume control down */
+#define XK_XF86AudioMute 0x1008FF12 /* Mute sound from the system */
+#define XK_XF86AudioRaiseVolume 0x1008FF13 /* Volume control up */
+#define XK_XF86AudioPlay 0x1008FF14 /* Start playing of audio > */
+#define XK_XF86AudioStop 0x1008FF15 /* Stop playing audio */
+#define XK_XF86AudioPrev 0x1008FF16 /* Previous track */
+#define XK_XF86AudioNext 0x1008FF17 /* Next track */
+
diff --git a/xlib/xcolors.c b/xlib/xcolors.c
index b5e45c9..36dc67c 100644
--- a/xlib/xcolors.c
+++ b/xlib/xcolors.c
@@ -345,6 +345,16 @@ XParseColor(
char *p;
Tcl_WideInt value = parseHex64bit(++spec, &p);
+ /*
+ * If *p does not point to the end of the string, there were invalid
+ * digits in the spec. Ergo, it is not a vailid color string.
+ * (Bug f0188aca9e)
+ */
+
+ if (*p != '\0') {
+ return 0;
+ }
+
switch ((int)(p-spec)) {
case 3:
colorPtr->red = US(((value >> 8) & 0xf) * 0x1111);