Friday, March 16, 2012

Solaris Workspace Menu

One of the smaller tasks I had at work was setting up customized workspace menus for users under a Solaris 10 environment.  I've verified that this also works on Trusted Solaris 8.  In fact, I'd bet that it's the same for most versions of Solaris, if not Unix.

Workspace menus are definied in dtwmrc files.  This defines windows options, the right click menu, and many key bindings.  The main workspace menu is found in "/etc/dt/config/C/sys.dtwmrc."  Failing finding another menu in a home directory, this is what will be used.

If another menu is be found in the current user's home directory's .dt folder (such as "/export/home/user/.dt/dtwmrc), that menu will take precedence.  If a role is assumed and another menu is found in the role's home directory's .dt folder (such as "/etc/security/home/primary admin/.dt/dtwmrc"), then that menu will take precendence.

Here is a sample (modified to be short) dtwmrc file:

  1. ###  
  2. #  
  3. # Root Menu Description  
  4. #  
  5. ###  
  6.   
  7. Menu DtRootMenu  
  8. {  
  9.     "Workspace Menu"            f.title  
  10.      no-label                f.separator  
  11.     "Refresh Workspace Display..."    f.refresh  
  12.     "Restart Workspace Manager..."    f.restart  
  13.      no-label                f.separator  
  14.     "Lock Display"            f.action LockDisplay  
  15.      "Log out..."            f.action ExitSession  
  16. }  
  17.   
  18. ###  
  19. #  
  20. # Front panel Manu Description  
  21. #  
  22. ###  
  23.   
  24. Menu DtPanelMenu  
  25. {  
  26.     Restore            _R    f.normalize  
  27.     Move            _M    f.move  
  28.     Minimize            _n    f.minimize  
  29.     Lower            _L    f.lower  
  30.     Refresh            _f    f.refresh  
  31.      no-label                f.separator  
  32.     "Log out..."        _o    f.action ExitSession  
  33. }  
  34.   
  35.   
  36. ###  
  37. #  
  38. # Sample Window Menu Description  
  39. # This menu description exists as a sample only.  
  40. # The normal window manager menu is built in.  
  41. #  
  42. ###  
  43.   
  44. Menu SampleWindowMenu  
  45. {  
  46.     "Restore"            _R            f.normalize  
  47.     "Move"            _M            f.move  
  48.     "Size"            _S            f.resize  
  49.     "Minimize"            _n            f.minimize  
  50.     "Maximize"            _x            f.maximize  
  51.     "Lower"            _L            f.lower  
  52.      no-label                        f.separator  
  53.     "Occupy Workspace..."    _O            f.workspace_presence  
  54.     "Occupy All Workspaces"    _A            f.occupy_all  
  55.     "Unoccupy Workspace"    _U            f.remove  
  56.      no-label                        f.separator  
  57.     "Close"            _C    Alt<Key>F4    f.kill  
  58. }  
  59.   
  60. ###  
  61. #  
  62. # Alternate Window Menu Description without accelerators  
  63. #  
  64. ###  
  65.   
  66. Menu NoAcceleratorWindowMenu  
  67. {  
  68.     "Restore"            _R    f.normalize  
  69.     "Move"            _M    f.move  
  70.     "Size"            _S    f.resize  
  71.     "Minimize"            _n    f.minimize  
  72.     "Maximize"            _x    f.maximize  
  73.     "Lower"            _L    f.lower  
  74.      no-label                f.separator  
  75.     "Occupy Workspace..."    _O    f.workspace_presence  
  76.     "Occupy All Workspaces"    _A    f.occupy_all  
  77.     "Unoccupy Workspace"    _U    f.remove  
  78.      no-label                f.separator  
  79.     "Close"            _C    f.kill  
  80. }  
  81.   
  82. ###  
  83. #  
  84. # Key Bindings Description  
  85. #  
  86. ###  
  87.   
  88. Keys DtKeyBindings  
  89. {  
  90.     Ctrl<key>c            root|icon|window    f.nop    # Copy  
  91.     Ctrl<key>v            root|icon|window    f.nop    # Paste  
  92.     Ctrl<key>x            root|icon|window    f.nop    # Cut  
  93. }  
  94.   
  95. ###  
  96. #  
  97. # Mouse Button Bindings Description  
  98. #  
  99. ###  
  100.   
  101. Buttons DtButtonBindings  
  102. {  
  103.   
  104.     <Btn1Down>        root            f.marquee_selection  
  105.     <Btn2Click>        root            f.toggle_frontpanel  
  106.     <Btn3Down>        root            f.menu  DtRootMenu  
  107. }  
  108.   
  109.   
  110. ###  
  111. #  
  112. # Defaults:   Window menus, key bindings, and mouse button bindings  
  113. #  
  114. ###  
  115.   
  116. Menu DefaultWindowMenu  
  117. {  
  118.     "Restore"    _R    Alt<Key>F5    f.normalize  
  119.     "Move"    _M    Alt<Key>F7    f.move  
  120.     "Size"    _S    Alt<Key>F8    f.resize  
  121.     "Minimize"    _n    Alt<Key>F9    f.minimize  
  122.     "Maximize"    _x    Alt<Key>F10    f.maximize  
  123.     "Lower"    _L    Alt<Key>F3    f.lower  
  124.     no-label                f.separator  
  125.     "Close"    _C    Alt<Key>F4    f.kill  
  126. }  
  127.   
  128. Keys DefaultKeyBindings  
  129. {  
  130.     Shift<Key>Escape        icon|window        f.post_wmenu  
  131.     Alt<Key>space        icon|window        f.post_wmenu  
  132.     Alt<Key>Tab            root|icon|window    f.next_key  
  133.     Alt Shift<Key>Tab        root|icon|window    f.prev_key  
  134.     Alt<Key>Escape        root|icon|window    f.next_key  
  135.     Alt Shift<Key>Escape    root|icon|window    f.prev_key  
  136.     Alt Ctrl Shift<Key>exclam    root|icon|window    f.set_behavior  
  137.     Alt<Key>F6            window            f.next_key transient  
  138. }  
  139.   
  140. Buttons DefaultButtonBindings  
  141. {  
  142.     <Btn1Down>        frame|icon    f.raise  
  143.     <Btn3Down>        icon        f.post_wmenu  
  144. }  
  145.   
  146. ###  
  147. #  
  148. # Designer Desktop Customization: $HOME/.dt/wsmenu.dtwmrc (if it exists)  
  149. # User Customization: $HOME/.dt/user.dtwmrc (if it exists)  
  150. #  
  151. ###  
  152.   
  153. INCLUDE  
  154. {  
  155.     $HOME/.dt/$LANG/wsmenu.dtwmrc  
  156.     $HOME/.dt/user.dtwmrc  
  157. }  

If you want to give user's special dtwmrc files based on some criteria (such as their group), you can use an executable file in the "/etc/dt/config/Xsession.d" directory. All scripts in this directory will be executed upon each login.

Here is a sample Xsession.d, which creates the user's home directory and copies in an admin dtwmrc if applicable. If they are not an admin, they will be using the default dtwmrc at /etc/dt/config/C/sys.dtwmrc.
  1. DTWMRC=/path/to/admin/dtwmrc  
  2. HOME_BASE=`/usr/bin/dirname ${HOME}`  
  3. HOME_DIR_OWNER=root  
  4. HOME_DIR_GROUP=bin  
  5. HOME_DIR_PERMS=drwxr-xr-x  
  6. SET_PERMS=755  
  7. ADMIN_GROUP=adm  
  8.   
  9. # If the directory doesn't exist, create it  
  10.   
  11. if [ ! -d ${HOME} ]  
  12. then  
  13.    /usr/bin/mkdir -p ${HOME}  
  14. fi  
  15.   
  16. # if the directory permissions are not correct, change them  
  17. D_PERMS=`/usr/bin/ls -ld ${HOME_BASE}/${USER} | /usr/bin/awk ' { print $1 } '`  
  18. D_OWNER=`/usr/bin/ls -ld ${HOME_BASE}/${USER} | /usr/bin/awk ' { print $3 } '`  
  19. D_GROUP=`/usr/bin/ls -ld ${HOME_BASE}/${USER} | /usr/bin/awk ' { print $4 } '`  
  20.   
  21. if [ "${D_OWNER}" != "${HOME_DIR_OWNER}" ] || \  
  22.    [ "${D_GROUP}" != "${HOME_DIR_GROUP}" ] || \  
  23.    [ "${D_PERMS}" != "${HOME_DIR_PERMS}" ]  
  24. then  
  25.    /usr/bin/chmod -R ${SET_PERMS} ${HOME_BASE}/$USER  
  26.    /usr/bin/chown -R ${HOME_DIR_OWNER}:${HOME_DIR_GROUP} ${HOME_BASE}/$USER  
  27. fi  
  28.   
  29. # if the user is an administrator, copy the admin workspace menu  
  30. USER_GROUP=`/usr/bin/groups $USER | /usr/bin/awk ' { print $1 } '`  
  31. if [ "${USER_GROUP}" = "${ADMIN_GROUP}" ]  
  32. then  
  33.    if [ ! -d ${HOME}/.dt ]  
  34.    then  
  35.       /usr/bin/mkdir ${HOME}/.dt  
  36.    fi  
  37.   
  38.    if [ ! -f ${HOME}/.dt/dtwmrc ]  
  39.    then  
  40.       /usr/bin/cp ${DTWMRC} ${HOME}/.dt/dtwmrc  
  41.    fi  
  42.   
  43.    /usr/bin/cp /opt/CONET/wm/dtwmrc.sysadm \  
  44.       /etc/security/tsol/home/sysadm/.dt/dtwmrc  
  45. fi