sizeinfo

MGS - In response to a question on Ask, and it shall be given. I knocked up this little package. The question/request was:

"When a user resizes a toplevel window I want to get a continuous feedback about the window's dimensions, so that I am able to display that on a label and user can set the exact size. The problem with <Configure> event bind is that it is fired at the end of the resizing operation.I want dimensions 'live' during resizing." by Neo [email protected].

I'm not sure if this completely satisfies, but here is a little utility to display the size and position of a toplevel (or any?) window in response to a <Configure> event.

 # sizeinfo.tcl --
 
 # Display window size info while resizing.
  
 # Version   : 0.0.1
 # Author    : Mark G. Saye
 # Email     : [email protected]
 # Copyright : Copyright (C) 2003
 # Date      : February 19, 2003
  
 # ======================================================================
 
   namespace eval sizeinfo {}
 
   package require Tk
   package provide sizeinfo 0.0.1
  
 # ======================================================================
  
 # create --
  
 proc sizeinfo::create {W} {
 
   toplevel     $W.sizeinfo -bd 0
   wm withdraw  $W.sizeinfo
   update idletasks
   wm transient $W.sizeinfo $W
   wm overrideredirect $W.sizeinfo 1
   label $W.sizeinfo.label -relief raised -bd 2
   pack  $W.sizeinfo.label
  
 }
  
 # ======================================================================
  
 # destroy --
  
 proc sizeinfo::destroy {W} {
  
   ::destroy $W.sizeinfo
  
 }
  
 # ======================================================================
  
 # refresh --
  
 proc sizeinfo::show {W w h x y} {
  
   variable $W
   upvar  0 $W _
  
   if { [info exists _(after)] } { after cancel $_(after) }
  
   if { ![winfo exists $W.sizeinfo] } { create $W }
  
   set label $W.sizeinfo.label
  
   $label configure -text "$w x $h + $x + $y"
  
   set x0 [expr {$x + ($w / 2)}]
   set y0 [expr {$y + ($h / 2)}]
  
   set _w [winfo reqwidth  $label]
   set _h [winfo reqheight $label]
  
   set _x [expr {$x0 - ($_w / 2)}]
   set _y [expr {$y0 - ($_h / 2)}]
  
   wm geometry $W.sizeinfo ${_w}x${_h}+${_x}+${_y}
  
  if { ![winfo ismapped $W.sizeinfo] } {
    wm deiconify $W.sizeinfo
     update idletasks
   }
  
   set _(after) [after 1000 [list sizeinfo::destroy $W]]
  
 }
  
 # ======================================================================
  
 proc sizeinfo::sizeinfo {W} {
  
   if { [string equal $W .] } { set w "" } { set w $W }
  
   bind $W <Configure> [list sizeinfo::show $w %w %h %x %y]
  
 }
  
 # ======================================================================
  
 # Demo code
  
   if { [info exists argv0] && [string equal [info script] $argv0] } {
     toplevel .t
     sizeinfo::sizeinfo .
     sizeinfo::sizeinfo .t
   }
  
 # ======================================================================

MSW / 20. Feb 2003

I think it is not satisfying the initial question. The problem was that the user should be able to do the resize continously and as well continously see the updated geometry info. Your package is nice, for it mimics a feature I like about some window managers :) But the asker also pointed out that the Configure Event only is triggered when the resizing is finished. I have looked a bit into the sources of fvwm1 which copies the resizing from the wm window manager (not our wm :), and it uses a MotionNotify Event (that is an X Event I believe, I'm no X diver), which our bind does not accept as argument. Yes, there is Motion, but it's kinda hard to get a motion when you are OUTSIDE the widget (as you are typically resizing with the BORDER of a window which is not part of the widget!) Fire up a wish and run the following to see what I mean (and resize . some after it)

 % bind . <Enter> { puts -nonewline stderr "\nEntering . " }
 % bind . <Leave> { puts -nonewline stderr "\nLeaving . " }
 % bind . <Motion> { puts -nonewline stderr "." }

So bindings don't qualify (you need them continously - and you don't get them), and I did not find the right thing which could be handled by wm protocol, although there might be something.

Still, I like sizeinfo :) - Oh and I know that my solution (sizepanel) is not satisfying the question either, but it offers a continous resizing with simultaneous information about the dimensions.


MGS - I'm not sure I really even understand the question. What do you mean by 'continuously'? I figured that showing the updated geometry, as the window is being resized, was what the OP was after. Anyway, wouldn't the resizing be done by a ConfigureNotify event, rather than a MotionNotify event? (Tk's bind doesn't handle that either.) I, like you, am no Xlib expert, though. Glad you like sizeinfo.


MSW (for ConfigureNotify vs. MotionNotify) could well be that I misread or misremember, don't have the my notes here atm:)

(for what the original poster (imho) was after): Imagine you start resizing a toplevel window. Let's say your window manager handles resizing by clicking on one of the corners of the border around the window, and then dragging the window "into shape". While you do that, each time it changes by one pixel, there is a little window which pops up at a well defined place (say upper left screen corner or middle of the window being resized) which updates information about the dimenions of the window while it is being resized.

So you'd start resizing a 200x200 window. You'd click on the upper left corner and drag one pixel diagonal into the window, the window would shrink to 199x199, and the little label (wherever it may be) would now immediately display 199x199, you drag one more pixel, it goes 198x198 etc. etc. Then you are done with the resize, and release the mousebutton, and it's only then where the tk event <Configure> fires.

My understanding is that the OP wanted to emulate the behaviour some window managers (like e.g. fvwm with my settings - dunno if it always does it, it's been ages since I configured it) show and which I explained above. The point is the immediate update of information as in contrast to the "delayed" update of information tcl can provide only when reacting on it - that's why I chose to take the stick rather and make tcl act as it can do that immediately.


MGS - Ah, I'm with you now. We seem to be talking about the same thing. I guess this is window manager dependent, 'coz with my sizeinfo package above, the info does update continuously. i.e. <Configure> events are being received while the window is being resized. FWIW, I'm using Linux/KDE 3.1 with the default kwin window manager. Maybe some window managers have an "opaque-move" option, or something similar.


MSW It won't work (continuously) neither with fvwm2 @ netbsd nor with openwin @ sunos 2.8/2.9. It's a pity that it's window manager dependant - on the other hand resizing a window is window manager dependant, too, eh ? ...


EB: OpaqueResize is the first feature I disable in a WM. Here is a way to mimic it through a resize handle:

 proc opaque_resize_handle {W} {

    # replace here with an image or whatever
    set handle [frame $W.resize_handle -background red -cursor sizing]
    place $handle -relx 1.0 -rely 1.0 -width 10 -height 10 -anchor se

    # bindings to resize W
    bind $handle <ButtonPress-1> {
        bind %W <Motion> \
            [string map [list WIDTH  [winfo width  [winfo parent %W]] \
                              HEIGHT [winfo height [winfo parent %W]]] \
                 {
                     wm geometry \
                         [winfo parent %W] \
                         [expr {WIDTH+(%%X - %X)}]x[expr {HEIGHT+(%%Y - %Y)}]
                 }]
    }
    bind $handle <ButtonRelease-1> {
        bind %W <Motion> {}
    }
 }

MSW: Neat!

MGS - See also Resize control and widget:resizeHandle