Updated 2018-09-20 13:27:19 by bll

brad.lanam.comp _at_ gmail.com

Currently unemployed.

Tcl/Tk, C, perl, php, shell, MySQL/MariaDB, HTML, CSS, porting, legacy systems, system administration.

website:

https://gentoo.com/ (registered 1992-03-26) No, this is not gentoo linux, they're at http://gentoo.org/ (registered 1999-10-04).

https://ballroomdj.org/

CV

  • B.S. Computer Science, minor in mathematics.
  • Debit/Credit processing system.
    • Seattle installation: Running on OS/2 in 35 grocery stores, all communicating to the same software running on SCO Unix at corporate which sent the transactions on to the bank.
    • California drug store: Handled 14 transactions per second processing checks.
  • Wrote the communications protocol for the California Smog Check 2 project.
  • Wrote the online epub reader for Apress utilizing Sphinx Search to search the entire Apress library.

Projects:

BallroomDJ: A ballroom music player written in tcl/tk.

 Other projects

All code I post here is under the zlib/libpng License.

Created Pages:

Major Contribution:


 ttk/combobox.tcl instate patch

When creating a megawidget with ttk::comboxbox, uplevel is used to run the combobox commands in the calling procedure's reference.

The ttk::combobox uses $cb instate disabled <script> syntax. In the case where <script> is { return }, an uplevel command cannot process the command correctly. This means that a disabled combobox will still drop down when clicked (and there are a couple of other spots also).

This patch changes the syntax to: if { [$cb instate disabled] } { return } for ttk::combobox and ttk::button.
--- library/ttk/button.tcl
+++ library/ttk/button.tcl
@@ -6,11 +6,11 @@
 # This doesn't seem to be conventional, but it's a nice way
 # to provide extra feedback while the grab is active.
 # (If the button is released off the widget, the grab deactivates and
 # we get a <Leave> event then, which turns off the "active" state)
 #
-# Normally, <ButtonRelease> and <ButtonN-Enter/Leave> events are 
+# Normally, <ButtonRelease> and <ButtonN-Enter/Leave> events are
 # delivered to the widget which received the initial <ButtonPress>
 # event.  However, Tk [grab]s (#1223103) and menu interactions
 # (#1222605) can interfere with this.  To guard against spurious
 # <Button1-Enter> events, the <Button1-Enter> binding only sets
 # the pressed state if the button is currently active.
@@ -48,11 +48,11 @@
 # activate --
 #      Simulate a button press: temporarily set the state to 'pressed',
 #      then invoke the button.
 #
 proc ttk::button::activate {w} {
-    $w instate disabled { return }
+    if { [$w instate disabled] } { return }
     set oldState [$w state pressed]
     update idletasks; after 100        ;# block event loop to avoid reentrancy
     $w state $oldState
     $w invoke
 }
--- library/ttk/combobox.tcl
+++ library/ttk/combobox.tcl
@@ -111,11 +111,11 @@
 #      depending on widget state and location of button press.
 #
 proc ttk::combobox::Press {mode w x y} {
     variable State
 
-    $w instate disabled { return }
+    if { [$w instate disabled] } { return }
 
     set State(entryPress) [expr {
           [$w instate !readonly]
        && [string match *textarea [$w identify element $x $y]]
     }]
@@ -179,11 +179,11 @@
 }
 
 ## Scroll -- Mousewheel binding
 #
 proc ttk::combobox::Scroll {cb dir} {
-    $cb instate disabled { return }
+    if { [$cb instate disabled] } { return }
     set max [llength [$cb cget -values]]
     set current [$cb current]
     incr current $dir
     if {$max != 0 && $current == $current % $max} {
        SelectEntry $cb $current
@@ -387,11 +387,11 @@
 #      Pop down the associated listbox.
 #
 proc ttk::combobox::Post {cb} {
     # Don't do anything if disabled:
     #
-    $cb instate disabled { return }
+    if { [$cb instate disabled] } { return }
 
     # ASSERT: ![$cb instate pressed]
 
     # Run -postcommand callback:
     #

 Notes:

Windows starts up the tcl scripts with wish, which uses the wish icon. Starting with tclsh uses the icon set using 'wm iconbitmap'. So to get the wanted icon to display, restart the program with tclsh.
package require Tk

set tclsh [info nameofexecutable] 
if { [regexp {wish\d*.exe} $tclsh] } { 
  regsub {wish\d*.exe} $tclsh tclsh.exe tclsh 
  exec $tclsh [info script] & 
  exit 
} 
wm iconbitmap . -default [file join $myimages bdj_icon.ico] 

ActiveState Tcl/Tk doesn't seem to get a dock icon. Everything seems to work with MacPorts Tcl/Tk.

Mac OSX application name in menubar:

a) Symlink the application name to the wish executable.

a1) It seems that CFBundleExecutable has to be the same name as the application name (this seems a bit odd -- the python examples don't have this issue).

a2) I needed to run wish during the installation to get the real wish executable path. It seems that stdout gets completely lost. I had to open a file and save the output there, then I could retrieve the information from the output file in the postinstall script.

a3) info nameofexecutable will return the symlink in (a).

b) Create Resources/Scripts/AppMain.tcl. This script is executed when (a) is run. Always. So I use:
set script [file normalize [file join \
    [file dirname [file dirname [file dirname [info script]]]] \
    MacOS MyApp.tcl]]

if { $argc > 0 } {
  set script [lindex $::argv 0]
  set ::argv [lrange $::argv 1 end]
}

source $script

so that the appropriate script is run. This does have the advantage that the application name in the menubar stays intact.

In general (from what I've read) it seems that the python users using the symlink trick have fewer problems getting their application name in the menubar. CFBundleExecutable doesn't have to match the application name, there's no startup script. Why is tk more complicated?

Why shrinking a window doesn't shrink the widget you want it to: https://groups.google.com/forum/#!topic/comp.lang.perl.tk/ZYD71t2tYDk

It would be nice if there was a way to configure this. Why doesn't shrinking the window honor the '-expand true' flags?

(Expanding the window honors the weight/expand flags. Shrinking the window uses the packing order of the widgets)