Tk Source Code

View Ticket
Login
Ticket UUID: 6ca257310a46a75f8a9bdfa3cf93f670bf009695
Title: wm resizable does not disable single dimension resizing
Type: Bug Version: 8.6.7
Submitter: programmingkid Created on: 2017-10-10 14:29:45
Subsystem: 66. Aqua Window Operations Assigned To: aku
Priority: 5 Medium Severity: Important
Status: Closed Last Modified: 2018-07-06 20:59:54
Resolution: Fixed Closed By: fvogel
    Closed on: 2018-07-06 20:59:54
Description:
The resizable() function takes two keyword arguments: width and height. Setting one of the arguments to False should make resizing that dimension impossible. What currently happens is if both width and height are False, resizing will not work. But if only one of the keywords are False then both dimensions will be resizable. Here is some sample python code that demonstrates this issue:

from Tkinter import *

root = Tk()
button = Button(root, text="Hello world")
button.pack(padx=30, pady=30)
root.resizable(width=True, height=False)
mainloop()


Additional information:
Bug observed on Mac OS 10.12.6. 
Tk Framework version: 8.6.7
Python version 2.7.14
Installed Python and Tk frameworks using the home-brew package manager like this:
brew install python --with-tcl-tk
User Comments: fvogel added on 2018-07-06 20:59:54:

Note: this fix also fixes test unixWm-33.6 that was failing on macOS as follows:

==== unixWm-33.6 Tk_WmCmd procedure, "resizable" option FAILED
==== Contents of test case:

    destroy .t2
    toplevel .t2 -width 200 -height 100
    wm geom .t2 +0+0
    set result ""
    lappend result [wm resizable .t2]
    wm resizable .t2 1 0
    lappend result [wm resizable .t2]
    wm resizable .t2 no off
    lappend result [wm resizable .t2]
    wm resizable .t2 false true
    lappend result [wm resizable .t2]
    destroy .t2
    set result

---- Result was:
{1 1} {1 1} {0 0} {1 1}
---- Result should have been (exact matching):
{1 1} {1 0} {0 0} {0 1}
==== unixWm-33.6 FAILED


fvogel added on 2018-07-04 07:14:40:
Merged to core-8-6-branch and trunk.

fvogel added on 2018-06-30 14:32:50:
So it looks like, the test does no longer fail, and I can resize in width or height with the other dimension fixed.

Well done, Marc, thanks!

marc_culler (claiming to be Marc Culler) added on 2018-06-30 13:52:17:
I think that commit [3752da03] handles this correctly.

marc_culler (claiming to be Marc Culler) added on 2018-06-30 13:23:44:
I noticed something related when I wrote that patch.  The "wm resizable" command
is handled by the function WmResizableCmd in tkMacOSXWm.c.  That function sets
or clears flags in two places: wmPtr->flags and wmPtr->attributes.
On my first attempt to write the patch I tried checking the flag in
wmPtr->flags.  That did not work.  Even though the code clearly sets the flag,
by the time that the windowWillResize callback is called the flag had somehow
been cleared.  On the other hand, the flag in wmPtr->attributes was still set.
So I used the attributes.

I have no idea what the author's reason was for using both the flags and the
attributes, nor do I know what strategy was being followed for managing them.
However, I did find some mysterious code on line 6284 of tkMacOSXWm.c which
appears to be responsible for clearing the resizing flags in wmPtr->flags after
they are set:

   6284             if (newAttributes & kWindowResizableAttribute) {
   6285                 wmPtr->flags &= ~(WM_WIDTH_NOT_RESIZABLE |
   6286                         WM_HEIGHT_NOT_RESIZABLE);
   6287             } else {
   6288                 wmPtr->flags |= (WM_WIDTH_NOT_RESIZABLE |
   6289                         WM_HEIGHT_NOT_RESIZABLE);
   6290             }

It looks to me like that code is forcing both flags to be on, or both flags
to be off, even though all 4 possibilities remain available in the attributes.
I think there should be 4 cases, using kWindowHoriontalZoomAttribute and
kWindowVerticalZoomAttribute rather than kWindowResizableAttribute which
presumably is the or of the other two.

fvogel added on 2018-06-30 06:28:40:

Thanks, it is indeed working now.

Oddly, what is still failing is test wm-resizable-2.1:

==== wm-resizable-2.1 setting and reading values FAILED
==== Contents of test case:

    wm resizable .t 0 1
    set result [wm resizable .t]
    wm resizable .t 1 0
    lappend result [wm resizable .t]
    wm resizable .t 1 1
    lappend result [wm resizable .t]

---- Result was:
1 1 {1 1} {1 1}
---- Result should have been (exact matching):
0 1 {1 0} {1 1}
==== wm-resizable-2.1 FAILED

Values given to "wm resizable" are correctly honored, since your fix is working, but these values are not given back when requested.


marc_culler (claiming to be Marc Culler) added on 2018-06-29 21:54:15:
See branch bug-6ca257310a for a proposed fix for this.

fvogel added on 2018-06-29 18:26:22:
Reproduced on macOS.

programmingkid added on 2017-10-16 18:44:11:
I tried fvogel's code and have verified that this problem does effect Tk on Mac OS X. This is exactly the program I used:

package require Tk
toplevel .t
wm resizable .t true false    ; # resizable in width only

bll added on 2017-10-11 20:54:24:
Works on Linux
Ticket reproduced on Mac OS X

I tested with both a root window and a toplevel window.

fvogel added on 2017-10-11 20:26:46:

Works for me on Windows. Example (this is Tk, no Tkinter here):

package require Tk
toplevel .t
wm resizable .t               ; # returns 1 1
wm resizable .t true true     ; # resizable in width and height
wm resizable .t true false    ; # resizable in width only
wm resizable .t false true    ; # resizable in height only
wm resizable .t false false   ; # not resizable

Ticked was reported for OS X but I an't check on OS X right now.