I put this page together because I have been spending a lot of time trying to get a full screen toplevel working under Windows. I wanted to share the code I came up with in hopes that it will be of use to someone. When I say fullscreen, I am not talking about a window that has been maximized. Instead, I mean a window that has no borders and takes up the entire screen. The main problem was that I could not create a main window that had no borders and still had an icon in the Windows task list (accessed via Alt-Tab). In order to make it work, I ended up creating a overrideredirect main window and a fake second window that would appear in the task bar. This code handles those messy details. # This file contains code to implement a Windows style # toplevel window that can be set to fullscreen mode. set _wintop(debug) 0 # Manage a given toplevel so that it can be made as # wide as the screen with no window borders. proc wintop_fullscreen_manage { t title } { global _wintop set _wintop(top) $t set _wintop(title) $title wm title $t $_wintop(title) wm protocol $t WM_DELETE_WINDOW {wintop_closed} bind $t {wintop_destroyed %W} bind $t {wintop_configure %W %w %h} bind $t {wintop_toggle_full_screen} bind $t {wintop_escape_full_screen} bind $t {wintop_focusin %W} bind $t {wintop_unmap %W} set _wintop(fullscreen) 0 set _wintop(fullscreen_iconic) 0 wintop_set_icon $t return } proc wintop_set_icon { top } { #global _wintop #wm iconbitmap $top top.ico } proc wintop_configure { W w h } { global _wintop if {$W != $_wintop(top)} { # Ignore events for sub widgets return } #puts "wintop_configure $W $w $h" if {![info exists _wintop(first_mapping)]} { set _wintop(first_mapping) 1 set _wintop(last_geom) [wm geom $_wintop(top)] set _wintop(top_width) [winfo width $_wintop(top)] set _wintop(top_height) [winfo height $_wintop(top)] } if {($w != $_wintop(top_width)) || ($h != $_wintop(top_height))} { set _wintop(top_width) $w set _wintop(top_height) $h wintop_resized $W $w $h } } proc wintop_resized { W w h } { global _wintop # Do stuff when window is resized! if {$_wintop(debug)} { puts "wintop_resized $w $h" } } # Invoked when the top window should be # closed down. proc wintop_closed { } { global _wintop # Invoke caller defined callback for close notification if {[info exists _wintop(closed_callback)]} { namespace eval :: $_wintop(closed_callback) } destroy $_wintop(top) } # Register cmd to invoke when wintop is closed proc wintop_closed_callback { cmd } { global _wintop set _wintop(closed_callback) $cmd } # Invoked when the top window has been # iconified via the wm (or wm command). proc wintop_iconified { } { global _wintop if {$_wintop(debug)} { puts "wintop_iconified" } if {$_wintop(fullscreen)} { # Switch to icon from full screen mode, we will # need to restore into full screen mode later on set _wintop(fullscreen_iconic) 1 wintop_toggle_fake_win 0 wm overrideredirect $_wintop(top) 0 if {$_wintop(debug)} { puts "set fullscreen_iconic mode flag in wintop_iconified" } wm iconify $_wintop(top) } # FIXME: Add callback } # Invoked when the wintop widget is in the # process of being destroyed. Cleanup state, # and ignore DestroyNotify events for children. proc wintop_destroyed { W } { global _wintop if {$W == $_wintop(top)} { if {$_wintop(debug)} { puts "wintop_destroyed $W" } unset _wintop(first_mapping) set _wintop(fullscreen) 0 set _wintop(last_geom) "" } } # Invoked when the main window gets focus, this happens # when the user clicks on the window, navigates to the # window via Alt-Tab, restores from a withdrawn state # and so on. proc wintop_focusin { W } { global _wintop if {$W != $_wintop(top)} { # Ignore events for sub widgets return } if {$_wintop(debug)} { puts "wintop_focusin" } # A focus in event can be delivered when the user clicks # on the icon in the taskbar, make sure to ignore it if {[wm state $_wintop(top)] == "iconic"} { return } # If the window was iconified while in full screen mode, # then return to full screen mode now if {$_wintop(fullscreen_iconic)} { if {$_wintop(debug)} { puts "restoring to full screen mode from iconic (mode is [wm state $_wintop(top)])" } set _wintop(fullscreen_iconic) 0 wintop_toggle_fake_win 1 wm overrideredirect $_wintop(top) 1 } elseif {$_wintop(fullscreen)} { # Clicking on the fullscreen window followed by # an Alt-Tab should show the fake window as the # current application raise $_wintop(fake) raise $_wintop(top) } } proc wintop_unmap { W } { global _wintop if {$W != $_wintop(top)} { # Ignore events for sub widgets return } if {$_wintop(debug)} { puts "wintop_unmap (current state is [wm state $_wintop(top)])" } if {!$_wintop(fullscreen) && [wm state $_wintop(top)] == "iconic"} { wintop_iconified } } proc wintop_toggle_full_screen {} { global _wintop if {$_wintop(fullscreen)} { # In full screen mode, return to normal border state if {$_wintop(last_state) == "normal"} { if {$_wintop(debug)} { puts "returning wintop to normal geom of $_wintop(last_geom)" } wm withdraw $_wintop(top) wm overrideredirect $_wintop(top) 0 wm state $_wintop(top) normal wm geom $_wintop(top) $_wintop(last_geom) wm deiconify $_wintop(top) } elseif {$_wintop(last_state) == "zoomed"} { if {$_wintop(debug)} { puts "returning wintop to zoomed state (last_geom is $_wintop(last_geom))" } wm state $_wintop(top) normal # Putting geom after overrideredirect causes 2 redraws wm geom $_wintop(top) $_wintop(last_geom) wm overrideredirect $_wintop(top) 0 wm state $_wintop(top) zoomed } else { error "unknown last state \"$_wintop(last_state)\"" } # Must set fullscreen before calling wintop_toggle_fake_win set _wintop(fullscreen) 0 wintop_toggle_fake_win 0 } else { if {[wm state $_wintop(top)] == "normal"} { set _wintop(last_state) "normal" set _wintop(last_geom) [wm geom $_wintop(top)] } elseif {[wm state $_wintop(top)] == "zoomed"} { set _wintop(last_state) "zoomed" } else { error "can't switch to full screen mode from \"[wm state $_wintop(top)]\"" } wm overrideredirect $_wintop(top) 1 wm state $_wintop(top) zoomed wintop_toggle_fake_win 1 set _wintop(fullscreen) 1 } } # Switch back to regular window mode if currently in full screen mode proc wintop_escape_full_screen { } { global _wintop if {$_wintop(fullscreen)} { wintop_toggle_full_screen } } # Enable/Disable a fake window that uses the same title bar # and icon but does not appear on the screen. When a user # Alt-Tab navigates to this window in full screen mode, # the zoomed toplevel will be raised and given the focus. proc wintop_toggle_fake_win { onoff } { global _wintop set _wintop(fake) .wtfake if {![winfo exists $_wintop(fake)]} { set t [toplevel $_wintop(fake) -width 100 -height 100 -bg red] wintop_set_icon $t wm geom $t +-10000+-10000 wm title $t $_wintop(title) wm protocol $t WM_DELETE_WINDOW {wintop_fake_closed} bind $t {wintop_fake_focusin} bind $t {wintop_fake_unmap} bind $t {wintop_fake_configure} } if {$onoff} { wm deiconify $_wintop(fake) # Always set to zoomed mode, so that maximize is # not an available option in the taskbar. wm state $_wintop(fake) zoomed if {$_wintop(debug)} { puts "enabled fake win in zoomed off screen mode" } } else { # wm state $_wintop(fake) normal wm withdraw $_wintop(fake) } } proc wintop_fake_focusin { } { global _wintop if {$_wintop(debug)} { puts "wintop_fake_focusin" } # If the fake window is is normal mode (not zoomed) # then the user must have selected "restore" from # the taskbar, leave full screen mode in that case if {[wm state $_wintop(fake)] == "normal"} { if {$_wintop(debug)} { puts "not in zoomed state ([wm state $_wintop(fake)]), must restore to non-zoomed" } wintop_toggle_full_screen } else { focus -force $_wintop(top) } } proc wintop_fake_closed { } { global _wintop destroy $_wintop(fake) wintop_closed } proc wintop_fake_unmap { } { global _wintop if {$_wintop(debug)} { puts "wintop_fake_unmap" } if {$_wintop(fullscreen)} { wintop_iconified } } proc wintop_fake_configure { } { global _wintop if {$_wintop(debug)} { puts "wintop_fake_configure" } } # Here is the example code that uses the procs above wm withdraw . destroy .t set t [toplevel .t] wintop_fullscreen_manage $t "Example" canvas $t.c -borderwidth 0 -highlightthickness 0 -bg blue pack $t.c -fill both -expand true # Once created, one should be able to switch from regular to # full screen mode via Alt-Return. While the code above worked for the most part, I have decided to give up on this approach for a couple of reasons. Lots of window resizing operations are visible to the end user and it makes the application look unprofessional. Also, when the application is busy, there are some moments where the fake window can be seen on screen. There are also real problems with the Windows virtual desktop where the fake window stays in one desktop while the real window is in another. All in all, I have decided to give up on this approach and focus on core Tk modifications to better support a full screen toplevel under Windows. [alove] Here is a much simpler solution. package require Tcl 8.4 ;# other versions?? wm title . "Minimize Test" wm geometry . [winfo screenwidth .]x[winfo screenheight .]+0+0 update idletasks ;# updates the full-screen wm overrideredirect . yes ;# removes window decorations wm attributes . -topmost yes ;# stays on top of other windows frame .x -highlightthickness 0 -bg #c8efff place .x -x 0 -y 0 -relwidth 1 -relheight 1 button .x.min -text "Minimize" -bg #ffdbff -font "arial 10 bold" \ -command x_iconify place .x.min -x [expr [winfo screenwidth .] - 140] -y 10 button .x.end -text "Close" -bg #ffdbff -font "arial 10 bold" \ -command "destroy ." place .x.end -x [expr [winfo screenwidth .] - 60] -y 10 bind . "wm overrideredirect . yes; focus -force ." bind . x_iconify proc x_iconify {} { wm overrideredirect . no wm iconify . } This works great on WindowsXP and I suppose it will work on other Win9x operating systems too. Just click on the "minimize" button or the key. The trick is to use to detect that the window is being deiconified. The "focus force ." is necessary for Windows, otherwise the doesn't work until you click on the window first. Adam Love -- [rdt] says on Linux, this works if the 'wm overrideredirect ...' comes before the 'wm geometry ...' if the 'wm attributes ...' is commented out as it gives an error.