Menu

#3029 Width too narrow on MacOS X

obsolete: 8.5.12
open-wont-fix
2
2012-12-03
2012-10-25
No

The -width option on tk_optionMenu results in a widget that is far too narrow to display that many characters on MacOS X. If -indicatoron is 1 the result is even worse (even less of the text is displayed). For example:

tk_optionMenu .om omVar DC1 DC2 DC3
.om configure -width 3
pack .om

this displays as expected on Linux, but the widget is far too narrow on MacOS X.

Discussion

  • Kevin Walzer

    Kevin Walzer - 2012-11-07

    This issue is easily avoided by not specifying a width and letting Tk draw the menubutton with default metrics, cf. omit the ".m configure -width 3" command. Under Aqua, the menubutton is drawn with a native widget, and a width of three pixels simply may not be compatible with those metrics.

     
  • Kevin Walzer

    Kevin Walzer - 2012-11-07
    • status: open --> pending-invalid
     
  • Kevin Walzer

    Kevin Walzer - 2012-11-07
    • assigned_to: hobbs --> wordtech
     
  • Russell Owen

    Russell Owen - 2012-11-07
    • status: pending-invalid --> open-invalid
     
  • Russell Owen

    Russell Owen - 2012-11-07

    Note that it is not an issue of 3 being intrinsically too narrow for Mac, but that any specified width is always too narrow for that many characters of text. Thus the correct fix (I believe) is to compute the width to send to the underlying widget differently on aqua than other platforms.

    Sometimes it is important to specify a width: for example if the user may choose options of varying width and the overall size of the parent window should remain the same.

     
  • Kevin Walzer

    Kevin Walzer - 2012-11-07

    "Thus the correct fix (I believe) is to compute the width to send
    to the underlying widget differently on aqua than other platforms."

    I don't understand this. Three pixels is three pixels. The following code implements the "width" parameter:

    Tk_Fill3DRectangle(tkwin, (Pixmap) macWin, mbPtr->normalBorder, 0, 0,
    Tk_Width(tkwin), Tk_Height(tkwin), 0, TK_RELIEF_FLAT);

    How should this be changed?

    There are limits to how we can manipulate a native widget. If you set a more narrow width than the button's customary metrics, it will happily draw that width, and clip the text in doing so.

    Can you post a screenshot of how this looks on other platforms, particularly Windows? Linux is also OK, but there we're not using a native widget.

     
  • Russell Owen

    Russell Owen - 2012-11-07

    On unix the width parameter specifies characters, not pixels, and the displayed widget shows that many characters whether indicatoron is true or false.

    I believe that is the standard, expected behavior, though I did not find the documentation for tk_optionMenu very enlightening. (Most of my coding is in python Tkinter, so I tend to rely on the Tkinter documentation. But that's no help when reporting bugs in tcl/tk).

    Thus I am confused when you talk about width being in pixels. It may be so on aqua, but surely that is a bug?

     
  • Russell Owen

    Russell Owen - 2012-11-07

    screen shot on unix with indicatoron=1

     
  • Russell Owen

    Russell Owen - 2012-11-07

    screen shot with indicatoron=0

     
  • Russell Owen

    Russell Owen - 2012-11-07

    I posted two screen shots on unix. I don't have access to Windows.

    I didn't realize tk_optionMenu had switched to using native widgets. If the desired behavior is that the widgets tend to look good with "reasonable" parameters on all platforms (I hope that width and indicatoron are both still considered reasonable), I would think the math for controlling width may have to be different for different platforms.

     
  • Kevin Walzer

    Kevin Walzer - 2012-11-07

    Under Cocoa, Tk uses this code to determine the width of a menubutton if a width flag is specified:

    if (mbPtr->width > 0) {
    int avgWidth = Tk_TextWidth(mbPtr->tkfont, "0", 1);
    width = mbPtr->width * avgWidth;
    }

    In other words, it calculates the width of a "O" character and then multiplies the width flag by the character width to determine what width the button is drawn at.

    I don't see another way to do this; this is consistent with the behavior documented in the man page, but obviously there seems to be some variance depending on the platform implementation.

     
  • Russell Owen

    Russell Owen - 2012-11-16

    Here is a simple way to reproduce it. It appears to be a bug in menubutton so I changed the category.

    menubutton .mb -text "DC1" -width 3 -indicatoron=0 # or 1
    pack .mb

    One possible fix:
    - increment width by 2 on aqua if indicatoron=0
    - increment width by 3 on aqua if indicatoron=1

     
  • Russell Owen

    Russell Owen - 2012-11-16
    • labels: 318715 --> 03. [*button] and [label]
     
  • Kevin Walzer

    Kevin Walzer - 2012-11-16

    I'm not yet persuaded that this is a bug that requires fixing. As discussed, it reflects the platform-native implementation. The suggested fix goes against that grain for, I suppose, better cross-platform compatibility, but it still strikes me as a hack that may cause unexpected side-effects.

    There are many aspects of Tk on both Windows and/or the Mac that don't conform 100% to the spec outlined in the man pages, such as button backgrounds, because of the platform-specific implementations. Historically the preference among Tk maintainers has been to err on the side of the platform-specific API, for better native integration on the platform. I concur with this preference.

     
  • Russell Owen

    Russell Owen - 2012-11-16

    I certainly see your point when it comes to attributes that are simply not supported by native widgets.

    But I consider -width a fundamentally different property -- at least for those widgets for which width is measured characters instead of pixels. Before Tcl/Tk 8.5 it always meant "leave enough room to display this many characters (of some size)". That was a very helpful definition because it meant that one could easily write a single code base that displayed the widget text properly on many platforms (unix, Mac and even Windows).

    I would beg you to consider using that same interpretation for width-in-characters in Tcl/Tk 8.5 as well. The fix is trivial and it's incredibly helpful for anyone writing cross-platform code (as I do).

     
  • Kevin Walzer

    Kevin Walzer - 2012-12-03
    • priority: 5 --> 2
    • status: open-invalid --> open-wont-fix
     
  • Kevin Walzer

    Kevin Walzer - 2012-12-03

    I've spent additional time reviewing various aspects of the menubutton, font, and button code under Tk-Cocoa, and I simply cannot determine what type of fix to apply that removes the issue you are seeing. I agree it's sub-optimal, and it's also quite possible that someone who knows the internal implementation of Tk under Cocoa better than me might be able to zero in on what to address, because that person would be more familiar with how the various bits (the button drawing code, the width calculation code, etc.) interact. To my eye they all look correct.

    Unfortunately, I don't have further time to investigate this issue further; I have already spent multiple hours looking at this in various respects (and not just discussing the issue here and on the mailing list, either), and have yet to come up with a better suggestion than my original one, which is to work around the issue at the script level, where such a fix can be trivially done. If you or anyone else is highly motivated to investigate this issue at the C/Objective-C level and sends a patch, I will quickly review it and commit it, if it works.