summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--library/menu.tcl4
-rw-r--r--tests/button.test48
-rw-r--r--tests/menu.test29
-rw-r--r--win/tkWinX.c31
4 files changed, 87 insertions, 25 deletions
diff --git a/library/menu.tcl b/library/menu.tcl
index a7aaa3f..b5dd88e 100644
--- a/library/menu.tcl
+++ b/library/menu.tcl
@@ -607,6 +607,10 @@ proc ::tk::MenuButtonDown menu {
if {![winfo viewable $menu]} {
return
}
+ if {[$menu index active] eq "none"} {
+ set Priv(window) {}
+ return
+ }
$menu postcascade active
if {$Priv(postedMb) ne "" && [winfo viewable $Priv(postedMb)]} {
grab -global $Priv(postedMb)
diff --git a/tests/button.test b/tests/button.test
index 708fc30..d4db317 100644
--- a/tests/button.test
+++ b/tests/button.test
@@ -3435,15 +3435,47 @@ test button-5.23 {ConfigureButton - -height option} -constraints {
test button-5.24 {ConfigureButton - computing geometry} -constraints {
fonts
} -body {
- button .b -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
- .b configure -text "Sample text" -width 10 -height 2
+ button .b -borderwidth 2 -highlightthickness 2 -font {Helvetica -12} \
+ -padx 30 -pady 20
+ # 1. button with text
+ .b configure -text "Sample text"
pack .b
- set result "[winfo reqwidth .b] [winfo reqheight .b]"
- .b configure -bitmap questhead
- lappend result [winfo reqwidth .b] [winfo reqheight .b]
-} -cleanup {
- destroy .b
-} -result {104 46 20 12}
+ set textwidth [font measure [.b cget -font] -displayof .b [.b cget -text]]
+ set expectedwidth [expr {$textwidth + 2*[.b cget -borderwidth] \
+ + 2*[.b cget -highlightthickness] + 2*[.b cget -padx]}]
+ incr expectedwidth 2 ; # added (hardcoded) in tkUnixButton.c
+ set result [expr $expectedwidth == [winfo reqwidth .b]]
+ set linespace [lindex [font metrics [.b cget -font] -displayof .b] 5]
+ set expectedheight [expr {$linespace + 2*[.b cget -borderwidth] \
+ + 2*[.b cget -highlightthickness] + 2*[.b cget -pady]}]
+ incr expectedheight 2 ; # added (hardcoded) in tkUnixButton.c
+ lappend result [expr $expectedheight == [winfo reqheight .b]]
+ # 2. button with a bitmap image
+ # there is no access to characteristics the predefined bitmaps,
+ # so define one as an image (copied from questhead.xbm)
+ set myquesthead [image create bitmap -data {
+ #define myquesthead_width 20
+ #define myquesthead_height 22
+ static unsigned char myquesthead_bits[] = {
+ 0xf8, 0x1f, 0x00, 0xac, 0x2a, 0x00, 0x56, 0x55, 0x00, 0xeb, 0xaf, 0x00,
+ 0xf5, 0x5f, 0x01, 0xfb, 0xbf, 0x00, 0x75, 0x5d, 0x01, 0xfb, 0xbe, 0x02,
+ 0x75, 0x5d, 0x05, 0xab, 0xbe, 0x0a, 0x55, 0x5f, 0x07, 0xab, 0xaf, 0x00,
+ 0xd6, 0x57, 0x01, 0xac, 0xab, 0x00, 0xd8, 0x57, 0x00, 0xb0, 0xaa, 0x00,
+ 0x50, 0x55, 0x00, 0xb0, 0x0b, 0x00, 0xd0, 0x17, 0x00, 0xb0, 0x0b, 0x00,
+ 0x58, 0x15, 0x00, 0xa8, 0x2a, 0x00};
+ }]
+ .b configure -image $myquesthead
+ set expectedwidth [expr {[image width $myquesthead] + 2*[.b cget -borderwidth] \
+ + 2*[.b cget -highlightthickness]}]
+ incr expectedwidth 2 ; # added (hardcoded) in tkUnixButton.c
+ lappend result [expr $expectedwidth == [winfo reqwidth .b]]
+ set expectedheight [expr {[image height $myquesthead] + 2*[.b cget -borderwidth] \
+ + 2*[.b cget -highlightthickness]}]
+ incr expectedheight 2 ; # added (hardcoded) in tkUnixButton.c
+ lappend result [expr $expectedheight == [winfo reqheight .b]]
+} -cleanup {
+ destroy .b
+} -result {1 1 1 1}
test button-5.25 {ConfigureButton - computing geometry} -setup {
button .b -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
diff --git a/tests/menu.test b/tests/menu.test
index aaadc86..05356e3 100644
--- a/tests/menu.test
+++ b/tests/menu.test
@@ -3878,6 +3878,35 @@ test menu-37.1 {menubar menues cannot be posted - bug 2160206} -setup {
destroy .m
} -result {1 {a menubar menu cannot be posted}}
+test menu-38.1 {Can't dismiss ttk::menubutton menu until mouse has hovered over it - bug fa32290898} -setup {
+} -constraints {macOrUnix} -body {
+ toplevel .top
+ ttk::menubutton .top.mb -text "Some menu";
+ menu .top.mb.m;
+ .top.mb.m add command -label "Item 1";
+ .top.mb.m add command -label "Item 2";
+ .top.mb configure -menu .top.mb.m;
+ pack .top.mb
+ update
+ # simulate mouse click on the menubutton, which posts its menu
+ event generate .top.mb <ButtonPress-1> -warp 1
+ update
+ after 50
+ event generate .top.mb <ButtonRelease-1>
+ update
+ # simulate mouse click on the menu again, i.e. without
+ # entering/leaving the posted menu
+ event generate .top.mb <ButtonPress-1>
+ update
+ after 50
+ event generate .top.mb <ButtonRelease-1>
+ update
+ # the menu shall have been unposted by the second click
+ winfo ismapped .top.mb.m
+} -cleanup {
+ destroy .top.mb.m .top.m .top
+} -result {0}
+
# cleanup
imageFinish
diff --git a/win/tkWinX.c b/win/tkWinX.c
index 12739ea..2180f52 100644
--- a/win/tkWinX.c
+++ b/win/tkWinX.c
@@ -81,6 +81,7 @@ typedef struct ThreadSpecificData {
TkDisplay *winDisplay; /* TkDisplay structure that represents Windows
* screen. */
int updatingClipboard; /* If 1, we are updating the clipboard. */
+ int surrogateBuffer; /* Buffer for first of surrogate pair. */
} ThreadSpecificData;
static Tcl_ThreadDataKey dataKey;
@@ -1208,23 +1209,19 @@ GenerateXEvent(
event.xkey.keycode = 0;
if ((int)wParam & 0xff00) {
int i, ch1 = wParam & 0xffff;
- char buffer[TCL_UTF_MAX+1];
+ char buffer[XMaxTransChars];
-#if TCL_UTF_MAX >= 4
- if ((((int)wParam & 0xfc00) == 0xd800)
- && (PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE) != 0)
- && (msg.message == WM_CHAR)) {
- MSG msg;
- int ch2;
-
- GetMessage(&msg, NULL, 0, 0);
- ch2 = wParam & 0xffff;
- ch1 = ((ch1 & 0x3ff) << 10) | (ch2 & 0x3ff);
- ch1 += 0x10000;
- event.xkey.nbytes = Tcl_UniCharToUtf(ch1, buffer);
- } else
-#endif
- event.xkey.nbytes = Tcl_UniCharToUtf(ch1, buffer);
+ if ((ch1 & 0xfc00) == 0xd800) {
+ tsdPtr->surrogateBuffer = ch1;
+ return;
+ }
+ if ((ch1 & 0xfc00) == 0xdc00) {
+ ch1 = ((tsdPtr->surrogateBuffer & 0x3ff) << 10) |
+ (ch1 & 0x3ff);
+ ch1 += 0x10000;
+ tsdPtr->surrogateBuffer = 0;
+ }
+ event.xkey.nbytes = Tcl_UniCharToUtf(ch1, buffer);
for (i=0; i<event.xkey.nbytes && i<XMaxTransChars; ++i) {
event.xkey.trans_chars[i] = buffer[i];
}
@@ -1249,7 +1246,7 @@ GenerateXEvent(
break;
case WM_UNICHAR: {
- char buffer[TCL_UTF_MAX+1];
+ char buffer[XMaxTransChars];
int i;
event.type = KeyPress;
event.xany.send_event = -3;