system tray

GUI construct in the lower right-hand corner, not the taskbar, that ... (RS adds:) holds little icons with mouse-over balloon behavior, and on double-click bring up minimized windows. Typically there are at least speaker volume control and clock; the Task manager also makes a tray icon that indicates CPU usage.

See Also

KDE
Includes information about targeting the KDE system tray from Tcl.
Freedesktop System Tray
An open specification. See freedock
TIP #325 : System Tray Access
A proposal to integrate systray functionality into Tk.

Microsoft Windows

winico or Win32api are necessary to manage the system tray.

TWAPI 3.1 systemtray command also provides for manipulating system tray icons and balloon help. To get any associated context menus to disappear when a pointer click occurs elsewhere, see Using Twapi 3.1 - SystemTray AddIcon , comp.lang.tcl, 2011-10-04. PRB: Menus for Notification Icons Do Not Work Correctly , Q135788.

The winico page contains a TWAPI example.


Tom Wilkason posted to comp.lang.tcl: "Here is an example from an http server that hides itself in the taskbar ...

;##
;# Callback to handle taskbar icon events
;# 
proc ht:iconCallback { message ico wparam lparam x y } {
    switch -- $message {
       WM_LBUTTONDOWN {
          wm deiconify .
       }
       WM_RBUTTONDOWN {
          wm withdraw .
       }
       default {}
    } ;# End Switch
}  
;# #
;#  Make window dissapear when it is minimized
;# 
if  {[catch {
    package require Winico
    if {[winico info] == ""} {  

       ;# Let GUI settle before setting icon
       update
       set ico [winico_seticon . [file join $home .. bin tclhttp.ico]]
       winico text $ico {tchHttp Web Server}
       winico taskbar add $ico \
         -callback [list ht:iconCallback %m %i %w %l %x %y]
      proc Minimize {w} {
         wm withdraw .
         console hide
      }
   } ;# end if
} result]} {
   console show
   puts stderr "$result"
} else {
   wm withdraw .
}

TFW 2004-03-03: Incidentally, there are distributions of winico that contain much more than is needed. You can use the following script to interface to the dll. Just save it as winico.tcl and create a package entry in the pkgIndex.tcl file for Winico 0.3.

In pkgIndex.tcl:

package ifneeded Winico 0.3 [list source [file join $dir winico.tcl]]

in winico.tcl

;# *************************************************************************
;# * File   : winico.tcl
;# * Purpose: Provide wrapper functions for the winico package
;# *          Loads the winico dll first.
;# *************************************************************************
load [file join [file dirname [info script]] winico03.dll]
###############################################################################
# Function   : winico_seticon
# Description: Be smart about selecting the most appropriate icon from the
#              icon file.
###############################################################################
proc winico_seticon { w icofile } {
    set ico [winico create $icofile]
    set screendepth [winfo screendepth .]
    set bigsize "32x32"
    set bigpos -1
    set bigdepth 0
    set smallsize "16x16"
    set smallpos -1
    set smalldepth 0
    foreach i [winico info $ico] {
       array set opts $i
       set depth    $opts(-bpp)
       set pos      $opts(-pos)
       set geometry $opts(-geometry)
       if { $geometry=="$bigsize" && $depth<=$screendepth } {
          if { $depth>$bigdepth } {
             set bigpos $pos
             set bigdepth $depth
          }
       } elseif { $geometry=="$smallsize" && $depth<=$screendepth } {
          if { $depth>$smalldepth } {
             set smallpos $pos
             set smalldepth $depth
          }
       }
    }
    if { $bigpos==-1 && $smallpos==-1 } {
       puts stderr "couldn't find $bigsize and $smallsize icons in $icofile"
       return $ico
    } elseif { $bigpos==-1 } {
       set bigpos $smallpos
       puts stderr "couldn't find $bigsize icons in $icofile"
    } elseif { $smallpos==-1 } {
       set smallpos $bigpos
       puts stderr "couldn't find $smallsize icons in $icofile"
    }
    puts stderr "big icon is $bigsize,bpp:$bigdepth,pos:$bigpos"
    puts stderr "small icon is $smallsize,bpp:$smalldepth,pos:$smallpos"
    winico setwindow $w $ico big   $bigpos
    winico setwindow $w $ico small $smallpos
    return $ico
}

###############################################################################
# Function   : winico_delall
# Description: Remove all icon instances
###############################################################################
proc winico_delall {} {
    foreach i [winico info] { winico delete $i }
}

###############################################################################
# Function   : winico_loadicon
# Description: Set up all big/small icons for a specified window
###############################################################################
proc winico_loadicon { w symbol } {
    set ico [winico load $symbol]
    winico setwindow $w $ico big
    winico setwindow $w $ico small
}
package provide Winico 0.3

JMN - 2021-10-07 14:17:34

I've used winico and twapi before to create a system tray icon with a popup context menu activated by button3

tk systray is nice to have built in now (especially as it enables use of 'tk sysnotify') - but I'm at a loss as to how to get the mouse click x and y coordinates in order to post my menu.

Any hints?


JMN - 2021-10-10 04:02:48

The answer is of course as simple as [winfo pointerx .] and [winfo pointery .]

I hadn't realized that this works outside the application windows - nice.