Skip to content

Instantly share code, notes, and snippets.

@ThomasAdam
Last active February 17, 2017 21:03
Show Gist options
  • Save ThomasAdam/7c19827686481383a6ff8a24bbb3bc2c to your computer and use it in GitHub Desktop.
Save ThomasAdam/7c19827686481383a6ff8a24bbb3bc2c to your computer and use it in GitHub Desktop.
FVWM: Per-state "tags" to have separate windows per desktop
# This explains how to make use of FVWM States in such a way as to emulate what other WMs make use of in terms of "groups" or
# "tags".
#
# Note that this doesn't (yet) encapsulate setting the EWMH Desktop, nor does it (yet) allow you to display more than one tag
# at a time, although that would be trivial.
#
# What this does do though, is, given tne prerequisite information on the number of Xinerama monitors there are, set up ten
# tags per monitor, and then tracks windows in these tags. Only one window can be in a tag at any one time, and sticky windows
# are supported.
# Generically assign all windows mapped to the current active tag on the current screen.
Style * InitialMapCommand PipeRead `echo AssignTag $[infostore.screen-$[w.screen]-ActiveTag]`
# Example showing how per-applications can be constrained to a particular tag.
Style Chromium InitialMapCommand AssignTag 2
Style * EWMHUseStackingOrderHints
# Turn off icons, etc. Hiding windows on tags relies on iconification, but really
# it's still the same page/desk the icons are on.
Style * !Icon
# Colorset definitions for the tag parts, etc.
Colorset 11 bg red, NoShape
Colorset 12 fg white, bg rgb:00/00/36, Plain, NoShape
Colorset 13 fg white, bg #A2A2A2
Colorset 14 fg white, bg blue
Colorset 15 fg white, bg #2F7E00
# What to add to the StartFunction
AddToFunc StartFunction
# FvwmEvent FE-BB will keep track of ensuring the FvwmButtons are updated on certain actions.
+ I Module FvwmEvent FE-BB
# The number of Xinerama screens present, starting from 0.
+ I InfoStoreAdd max-screen 1
+ I SetupTags
+ I PipeRead `for i in $(seq 0 $[infostore.max-screen]); do \
echo "SetupFvwmButtons $i"; done`
# Wait a little bit till the end, so that the windows are counted.
+ I Schedule 100 All CountAndTitleButtons
# Set up how many tags per output will be present.
DestroyFunc SetupTags
AddToFunc SetupTags
+ I PipeRead `for i in $(seq 0 $[infostore.max-screen]); do \
min_tag=$((i * 10)); max_tag=$((min_tag + 9)); \
echo "InfoStoreAdd screen-$i-ActiveTag $min_tag"; \
echo "InfoStoreAdd screen-$i-PrevTag $max_tag"; \
done`
# FIXME: Calculate this!
+ I CreateTagCounts 0 19
# One FvwmButtons instance per monitor.
DestroyFunc SetupFvwmButtons
AddToFunc SetupFvwmButtons
+ I DestroyModuleConfig FB-BB-$0:*
+ I KillModule FvwmButtons FB-BB-$0
+ I *FB-BB-$0: Back blue
+ I *FB-BB-$0: Fore white
+ I *FB-BB-$0: Rows 1
+ I *FB-BB-$0: Frame 0
+ I *FB-BB-$0: Geometry $[vp.width]x16+0+0@$0
+ I PipeRead `for tagname in $(seq $[infostore.screen-$0-ActiveTag] $[infostore.screen-$0-PrevTag]); do echo "*FB-BB-$0: (30x1, Id Desk${tagname}$0, Center, Title $tagname)"; done`
+ I *FB-BB-$0: (600x1, Id WinTitle, Center, Title "...", Back purple)
+ I *FB-BB-$0: (380x1, Right, Padding 0 0, Frame 0, Swallow (UseOld, NoHints) "bar" \
`Exec exec conky | lemonbar -g 380x16 -p -b -B'#0000FF' -u2`)
+ I Module FvwmButtons FB-BB-$0
# Other resolutions:
#
# + I PipeRead `for tagname in \
# $(seq $[infostore.screen-$0-ActiveTag] $[infostore.screen-$0-PrevTag]); \
# do \
# echo "*FB-BB-$0: (28x1, Id Desk${tagname}$0, Center, Title $tagname)"; \
# done`
#+ I *FB-BB-$0: (600x1, Id WinTitle, Center, Title "...", Back purple)
#+ I *FB-BB-$0: (1030x1, Right, Padding 0 0, Frame 0, Swallow (UseOld, NoHints) \
# "bar" `Exec exec conky | lemonbar -g 1030x16 -p -b -B'#0000FF' -u2`)
# The number of windows on each tag.
DestroyFunc CreateTagCounts
AddToFunc CreateTagCounts
+ I PipeRead `for i in $(seq $0 $1); do echo "InfoStoreAdd tag-$i 0"; done`
DestroyFunc CountAndTitleButtons
AddToFunc CountAndTitleButtons
+ I CountWindowsOnTag $[infostore.$[w.id]]
+ I PipeRead `[ $[infostore.tag-$[infostore.$[w.id]]] -gt 0 ] && \
echo "SendToModule FB-BB-$[w.screen] ChangeButton Desk$[infostore.$[w.id]]$[w.screen] Title $[infostore.$[w.id]]:*"; \
[ $[infostore.tag-$[infostore.$[w.id]]] -le 0 ] && \
echo "SendToModule FB-BB-$[w.screen] ChangeButton Desk$[infostore.$[w.id]]$[w.screen] Title $[infostore.$[w.id]]"`
DestroyFunc ChangeButtons
AddToFunc ChangeButtons
+ I SendToModule FB-BB-$[pointer.screen] ChangeButton WinTitle Title $[w.name]
+ I SendToModule FB-BB-$[pointer.screen] ChangeButton Desk$[infostore.screen-$[pointer.screen]-PrevTag]$[pointer.screen] Colorset 14
+ I SendToModule FB-BB-$[pointer.screen] ChangeButton Desk$[infostore.screen-$[pointer.screen]-ActiveTag]$[pointer.screen] Colorset 15
DestroyFunc AssignTag
AddToFunc AssignTag
+ I ThisWindow (State $0) Break
+ I PipeRead `echo "MovetoScreen $[infostore.tag-$0-screen]"`
+ I Schedule 100 PipeRead `[ $[infostore.screen-$[w.screen]-ActiveTag] = $0 ] || \
echo "WindowId $[w.id] Iconify off"`
+ I PipeRead `echo "State $0"; \
echo "InfoStoreAdd $[w.id] $0"; \
echo "InfoStoreAdd CountWindowsOnTag $0"; \
echo "All (State $0) CountAndTitleButtons"`
DestroyFunc CountWindowsOnTag
AddToFunc CountWindowsOnTag
+ I SetEnv TCOUNT 0
+ I All (State $0) PipeRead `echo SetEnv TCOUNT $((TCOUNT + 1))`
+ I InfoStoreAdd tag-$0 $[TCOUNT]
+ I UnsetEnv TCOUNT
DestroyFunc SwitchTagsRelative
AddToFunc SwitchTagsRelative
+ I SetEnv PSCREEN $[pointer.screen]
+ I SetEnv CUR_TAG $[infostore.screen-$[PSCREEN]-ActiveTag]
+ I PipeRead `SCR="$CUR_TAG"; NEXT=$((SCR $0 1)); \
[ $PSCREEN -eq 0 ] && { \
[ $NEXT -lt 0 ] && NEXT=9; \
[ $NEXT -gt 9 ] && NEXT=0; \
}; \
[ $PSCREEN -eq 1 ] && { \
[ $NEXT -lt 10 ] && NEXT=19; \
[ $NEXT -gt 19 ] && NEXT=10; \
}; \
echo "SetEnv NEXT $NEXT"`
+ I SwitchTags $[pointer.screen] $[CUR_TAG] $[NEXT]
+ I UnsetEnv PSCREEN
+ I UnsetEnv CUR_TAG
# Use the stacking order when iconifying/uniconfying.
DestroyFunc SwitchTags
AddToFunc SwitchTags
# Screen == $0
# Current Tag == $1
# Next Tag == $2
+ I All Reverse UseStack (State $1, !Sticky, CurrentScreen) Iconify on
+ I All UseStack (State $2, !Sticky, CurrentScreen) Iconify off
+ I InfoStoreAdd screen-$0-PrevTag $1
+ I InfoStoreAdd screen-$0-ActiveTag $2
+ I ChangeButtons
DestroyFunc TransparencyMove
AddToFunc TransparencyMove
+ M PipeRead `echo Move`
+ M AssignTag $[infostore.screen-$[w.screen]-ActiveTag]
DestroyFunc UrgencyFunc
AddToFunc UrgencyFunc
+ I ThisWindow (Focused) Break
+ I WindowStyle Colorset 11
+ I SendToModule FB-BB-$[w.screen] ChangeButton Desk$[infostore.$[w.id]]$[w.screen] Colorset 11
DestroyFunc UrgencyDoneFunc
AddToFunc UrgencyDoneFunc
+ I DestroyWindowStyle
+ I ChangeButtons
# Module definitions
DestroyModuleConfig FE-BB:*
*FE-BB: add_window CountAndTitleButtons
*FE-BB: focus_change ChangeButtons
*FE-BB: string ChangeButtons
*FE-BB: property_change ChangeButtons
*FE-BB: destroy_window CountAndTitleButtons
# Key / Mouse bindings
Key bracketright A 4 SwitchTagsRelative +
Key bracketleft A 4 SwitchTagsRelative -
Mouse 1 W 4 TransparencyMove
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment