Version 2 of A very simple window manager

Updated 2015-07-13 12:57:35 by TAB

I had to open a TK GUI, which is not under control of the underlaying window manager.

  • open a toplevel always steals the focus
  • no window manager controls are needed.

This script here his my solution for

  • handling the focus
  • moving the window
package require Tk

package provide vlxwm 0.1

namespace eval vlxwm { }
namespace eval vlxwm::focus {
    variable helper
}
namespace eval vlxwm::move {
    variable controlID
}

#######################################################################
proc vlxwm::focus::save {} {
    variable helper
    if ![info exists helper] {
        ::set helper .xxx[clock clicks]
        # create a new toplevel window
        # this is controlled by the window manager
        toplevel $helper
        wm geometry $helper 0x0-1-1
    }
    raise $helper
    update 
    wm withdraw $helper
    after 250
}
proc vlxwm::focus::restore {} {
    variable helper
    if ![info exists helper] return
    # destroy this toplevel and windows manager focus on the last know window
    # which is not this gui, because of overrideredirect
    destroy $helper
    unset helper
}
proc vlxwm::focus::set {w} {
    save
    ::bind $w <Leave> vlxwm::focus::restore 

    wm overrideredirect  [winfo toplevel $w] 0
    raise  $w
    focus -force $w
    wm overrideredirect  [winfo toplevel $w] 1
}
proc vlxwm::focus::bind {w} {
    ::bind $w <Leave>         +[list vlxwm::focus::restore]
    ::bind $w <ButtonPress-1> +[list vlxwm::focus::set %W]
}
#######################################################################
# enable the move of the window
proc vlxwm::move::Enable {wg x y} {
    variable controlID
    control  [winfo toplevel $wg] $x $y
}
proc vlxwm::move::Disable {} {
    variable controlID
    after cancel $controlID
}
proc vlxwm::move::control {wg x y} {
    variable controlID
    if [info exists controlID] {after cancel $controlID}

    # top left corner of toplevel
    set tx [winfo x $wg]
    set ty [winfo y $wg]

    # get current possion
    set npx [winfo pointerx $wg]
    set npy [winfo pointery $wg]

    set dpx [expr {$npx - $x}]
    set dpy [expr {$npy - $y}]

    # new toplevel position
    set ntx [expr {$tx + $dpx}]
    set nty [expr {$ty + $dpy}]
    wm geometry $wg +${ntx}+${nty}
    set controlID [after 10 [list vlxwm::move::control $wg $npx $npy]]
}

proc vlxwm::move::bind {wg} {
    ::bind $wg <ButtonPress-1>   +[list vlxwm::move::Enable %W %X %Y]
    ::bind $wg <ButtonRelease-1> +[list vlxwm::move::Disable]
}

##########################################################
##########################################################
proc leave args {
    puts "gui left"

}

proc press args {
    puts "pressed"
}

wm withdraw .
toplevel .my -bg black -border 5
wm overrideredirect  .my 1
label  .my.move -text move -bg seashell
text   .my.text -height 10 -width 40
button .my.exit -command exit -text exit


grid .my.move -sticky we
grid .my.text -sticky nwse
grid .my.exit -sticky nwse

::bind .my.text  <ButtonPress-1>   [list press]
::bind .my       <Leave>           [list leave]

vlxwm::move::bind .my.move
vlxwm::focus::bind .my.text