Version 1 of A very simple window manager

Updated 2015-07-13 12:39:54 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

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 
    after 100
}
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 [winfo toplevel $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]
}


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

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