Version 7 of GooWee

Updated 2004-10-07 15:29:04 by jcw

This is another window manager for weeApps. The code below sets up a main window with four MDI-like app windows, one anchored to each corner.

There's a starkit at [L1 ] which adds a wrapper around this with Keith Vetter's Rush Hour game in window #1 and Steve Redler's weeCalc in window #3. The API for this is one big hack, basically it overrides the pack, button, etc commands - trying to make a script think that "." is the top level, while GooWee turns it into a frame. The illusion breaks down whem calling widgets directly, so ".t ..." needs to be changed to "gw .t ..." everywhere in the original script. A single line at the top ensures that the Rush Hour script continues to work when launched by itself, i.e. in the normal "." toplevel:

  proc gw {args} { uplevel 1 $args }; catch ::gw::init ;# GooWee preamble

http://www.equi4.com/pub/etc/goowee.png

Anyway, here is "goowee.tcl", a (densely coded) GooWee wanna-be-a-desktop-manager. It presents a demo desktop when launched as is:

  # GooWee - A little desktop for little windows
  # jcw, 2004-10-07

  package require Tk

  bind . <F5> { destroy . } ;# ramdebugger convenience

  namespace eval gw {
    variable version 0.1

    proc layoutScreen {} {
      variable version
      wm title . "GooWee $version"
      set bg #fffff0
      . configure -bg $bg
      pack [frame .desk -bg $bg -height 500 -width 750] -expand 1 -fill both
      pack [frame .ctl -height 50] -fill x -padx 3 -pady 3
      text .ctl.t -bg $bg -height 2 -bd 0 -highlightcolor #c0c0c0
      pack .ctl.t -fill both
      .ctl.t insert end "Press F1..F4 to switch or F5 to quit. "
                # fgcolor bgcolor -----arrow-bitmask----- hside vtitle
      createTop 1 #ffcccc #fff0f0 80/C0/E0/F0/F8/FC/FE/FF right bottom 
      createTop 2 #ccffcc #f0fff0 01/03/07/0F/1F/3F/7F/FF left  bottom 
      createTop 3 #ccccff #f0f0ff FF/7F/3F/1F/0F/07/03/01 left  top 
      createTop 4 #dddddd #f0f0f0 FF/FE/FC/F8/F0/E0/C0/80 right top 
      focusOn 1
    }
    proc createTop {n fgcolor bgcolor bits hside vtitle} {
      variable arrows
      if {![info exists arrows($n)]} {
        set arrows($n) [makeArrow $bits]
      }
      set w .desk.f$n
      frame $w -bg white -highlightthickness 1 \
        -highlightbackground $fgcolor -highlightcolor $fgcolor
      frame $w.bar
      label $w.bar.t -bg $bgcolor -text F$n -anchor w
      label $w.bar.a -bg $bgcolor -image $arrows($n) -width 15
      frame $w.top -bg white -bd 0
      pack $w.bar -fill x -side $vtitle
      pack $w.bar.a -fill y -side $hside
      pack $w.bar.t -expand 1 -fill x -side $hside
      pack $w.top -expand 1 -fill both -side $vtitle
      setSize $n 350 200
      bind . <F$n> "::gw::focusOn $n"
      bind $w <FocusIn> "::gw::setColor $n $fgcolor; raise $w"
      bind $w <FocusOut> "::gw::setColor $n $bgcolor"
      bind $w.bar.t <1> "::gw::focusOn $n"
      bind $w.bar.a <1> "::gw::focusOn $n %x %y"
      bind $w.bar.a <B1-Motion> "::gw::trackSize $n %x %y"
    }
    proc makeArrow {b} {
      set d [string map [list #m 0x[string map {/ ,0x} $b]] {
        #define _width 8
        #define _height 8
        static char _bits[] = { #m };
      }]
      return [image create bitmap -data $d]
    }
    proc focusOn {n {x ""} {y ""}} {
      variable rx $x ry $y
      focus .desk.f$n.top
    }
    proc trackSize {n x y} {
      variable rx
      variable ry
      set w .desk.f$n
      set ax [string map {1 + 2 - 3 - 4 +} $n]
      set ay [string map {1 + 2 + 3 - 4 -} $n]
      set nx [expr [winfo width $w] $ax ($x-$rx)]
      set ny [expr [winfo height $w] $ay ($y-$ry)]
      setSize $n $nx $ny
    }
    proc setSize {n nx ny} {
      #XXX cannot use winfo before geometry has been determined
      #XXX but winfo will be required to deal with desk resizing
      set sx [.desk cget -width] ;#set sx [winfo width .desk]
      set sy [.desk cget -height] ;#set sy [winfo height .desk]
      incr sx -3
      if {$nx > $sx-25} { set nx [expr {$sx-25}] }
      if {$ny > $sy-30} { set ny [expr {$sy-30}] }
      if {$nx < 45} { set nx 45 }
      if {$ny < 25} { set ny 25 }
      switch $n 1 - 4 { set x 3 } default { set x [expr {$sx-$nx}] }
      switch $n 1 - 2 { set y 3 } default { set y [expr {$sy-$ny}] }
      place .desk.f$n -width $nx -height $ny -x $x -y $y
    }
    proc setColor {n color} {
      set w .desk.f$n
      $w.bar.t configure -bg $color
      $w.bar.a configure -bg $color
    }

    layoutScreen
  }

NEM Regarding the hack to get each app to see a different toplevel widget, I seem to remember that child interps can load Tk with a particular container widget acting as the root for that interp. [L2 ] has details - it's part of the Safe Base package.

jcw - Aha! Thanks, I now also found Embedded Toplevels. Right now, the GooWee "toplevels" are frames. Given that I don't want the usual windows manager borders/decorations, I assume that the way to do it is: 1) create new frameless toplevel, 2) embed it in frame via the -use & -container options, 3) pass the resulting toplevel to scripts (trapping wm title), or 4) use the ::save::loadTk approach with a slave interpreter, as you suggest. Interesting - I never knew such things were possible. Will need to explore the x-platform combinations. Inter-process is less important for me.

Brian Theado - I dug into the ::safe::loadTk a bit and here is a way of doing it using a plain slave interpreter instead of a safe slave interpreter. I guess "package require Tk" looks at the contents of argv for options such as -use [L3 ].

 package require Tk
 pack [frame .f -container 1]
 interp create s
 s eval [list set argv [list -use [winfo id .f]]]
 s eval {
    package require Tk
    pack [text .t]
 }

To illustrate that the slave's text widget is embedded, try:

 pack forget .f

and see the text widget disappear.

jcw - W(h)ee! GooWee now runs unmodified scripts with a . top-level in a non-safe slave interpreter (only tested on Linux so far) - yes! I only had to wrap "wm deiconify" in a catch in SR's weeCalc, to make it run like a main app. Lost the ability to set the title, will be fixed later.


Category GUI Category Application