From 3147e53de56d78b75db674135ff4782d49467c73 Mon Sep 17 00:00:00 2001 From: patthoyts Date: Wed, 30 Dec 2009 00:24:27 +0000 Subject: Patch 2879789: Make torn-off menu entrys activate across whole window The torn-off menu entries do not activate except immediately over the label or icon. If the window containing the torn-off menu is expanded then a lot of dead space may be created, including the cascade arrow. This patch fixes this making the whole width for any menu entry capable of activation when the pointer hovers over the item. --- ChangeLog | 6 ++++++ generic/tkMenu.c | 38 +++++++++++++++++++++++++------------- tests/menu.test | 43 ++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 73 insertions(+), 14 deletions(-) diff --git a/ChangeLog b/ChangeLog index cc65f9a..50a4bdd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2009-12-30 Pat Thoyts + + * generic/tkMenu.c: Torn off menu items are only activated over + * tests/menu.tcl: a limited region of the window. Fixed to make + the whole width of a menu item activate the entry. [Patch 2879789] + 2009-12-27 Pat Thoyts * win/tkWinMenu.c: Highlight for cascade items in torn-off menus diff --git a/generic/tkMenu.c b/generic/tkMenu.c index 479dd0c..7c95f32 100644 --- a/generic/tkMenu.c +++ b/generic/tkMenu.c @@ -12,7 +12,7 @@ * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkMenu.c,v 1.53 2009/12/09 10:45:30 dkf Exp $ + * RCS: @(#) $Id: tkMenu.c,v 1.54 2009/12/30 00:24:27 patthoyts Exp $ */ /* @@ -2928,16 +2928,16 @@ MenuDoYPosition( * * GetIndexFromCoords -- * - * Given a string of the form "@int", return the menu item corresponding - * to int. + * Given a string of the form "@integer", return the menu item + * corresponding to the provided y-coordinate in the menu window. * * Results: * If int is a valid number, *indexPtr will be the number of the - * menuentry that is the correct height. If int is invaled, *indexPtr + * menuentry that is the correct height. If int is invalid, *indexPtr * will be unchanged. Returns appropriate Tcl error number. * * Side effects: - * If int is invalid, interp's result will set to NULL. + * If int is invalid, interp's result will be set to NULL. * *---------------------------------------------------------------------- */ @@ -2952,6 +2952,7 @@ GetIndexFromCoords( int x, y, i; const char *p; char *end; + int x2, borderwidth, max; TkRecomputeMenu(menuPtr); p = string + 1; @@ -2959,6 +2960,8 @@ GetIndexFromCoords( if (end == p) { goto error; } + Tk_GetPixelsFromObj(interp, menuPtr->tkwin, + menuPtr->borderWidthPtr, &borderwidth); if (*end == ',') { x = y; p = end + 1; @@ -2967,23 +2970,32 @@ GetIndexFromCoords( goto error; } } else { - Tk_GetPixelsFromObj(interp, menuPtr->tkwin, - menuPtr->borderWidthPtr, &x); + x = borderwidth; } + *indexPtr = -1; + + /* set the width of the final column to the remainder of the window + * being aware of windows that may not be mapped yet. + */ + max = Tk_IsMapped(menuPtr->tkwin) + ? Tk_Width(menuPtr->tkwin) : Tk_ReqWidth(menuPtr->tkwin); + max -= borderwidth; + for (i = 0; i < menuPtr->numEntries; i++) { + if (menuPtr->entries[i]->entryFlags & ENTRY_LAST_COLUMN) { + x2 = max; + } else { + x2 = menuPtr->entries[i]->x + menuPtr->entries[i]->width; + } if ((x >= menuPtr->entries[i]->x) && (y >= menuPtr->entries[i]->y) - && (x < (menuPtr->entries[i]->x + menuPtr->entries[i]->width)) + && (x < x2) && (y < (menuPtr->entries[i]->y + menuPtr->entries[i]->height))) { + *indexPtr = i; break; } } - if (i >= menuPtr->numEntries) { - /* i = menuPtr->numEntries - 1; */ - i = -1; - } - *indexPtr = i; return TCL_OK; error: diff --git a/tests/menu.test b/tests/menu.test index dccdf52..1659c58 100644 --- a/tests/menu.test +++ b/tests/menu.test @@ -5,7 +5,7 @@ # Copyright (c) 1998-1999 by Scriptics Corporation. # All rights reserved. # -# RCS: @(#) $Id: menu.test,v 1.23 2009/01/13 01:46:06 patthoyts Exp $ +# RCS: @(#) $Id: menu.test,v 1.24 2009/12/30 00:24:27 patthoyts Exp $ package require tcltest 2.2 namespace import ::tcltest::* @@ -3312,6 +3312,47 @@ test menu-22.2 {GetIndexFromCoords} -setup { } -cleanup { deleteWindows } -result {0} +test menu-22.3 {GetIndexFromCoords: mapped window, y only} -setup { + deleteWindows +} -body { + menu .m1 + .m1 add command -label "test" + .m1 configure -tearoff 0 + tk_popup .m1 0 0 + tkwait visibility .m1 + .m1 index @5 +} -cleanup { + deleteWindows +} -result {0} +test menu-22.4 {GetIndexFromCoords: mapped window x,y} -setup { + deleteWindows +} -body { + menu .m1 + .m1 add command -label "test" + .m1 configure -tearoff 0 + tk_popup .m1 0 0 + tkwait visibility .m1 + update + set x [expr {[winfo width .m1] - [.m1 cget -borderwidth] - 1}] + .m1 index @$x,5 +} -cleanup { + deleteWindows +} -result {0} +test menu-22.5 {GetIndexFromCoords: mapped wide window} -setup { + deleteWindows +} -body { + menu .m1 + .m1 add command -label "test" + .m1 configure -tearoff 0 + tk_popup .m1 0 0 + tkwait visibility .m1 + wm geometry .m1 200x100 + update + set x [expr {[winfo width .m1] - [.m1 cget -borderwidth] - 1}] + .m1 index @$x,5 +} -cleanup { + deleteWindows +} -result {0} test menu-23.1 {RecursivelyDeleteMenu} -setup { deleteWindows -- cgit v0.12