aboutsummaryrefslogtreecommitdiff
path: root/.config/cow/cow.conf
diff options
context:
space:
mode:
Diffstat (limited to '.config/cow/cow.conf')
-rw-r--r--.config/cow/cow.conf637
1 files changed, 379 insertions, 258 deletions
diff --git a/.config/cow/cow.conf b/.config/cow/cow.conf
index afbc63f..0d66370 100644
--- a/.config/cow/cow.conf
+++ b/.config/cow/cow.conf
@@ -1,9 +1,11 @@
# cow window manager configuration
#
-# This file is read directly from cow(1) but every command herein can be
-# sent to cow(1) via it's IPC mechanism with moocow(1).
+# cow(1) reads this file at startup. The same commands can be sent to a
+# running instance with moocow(1).
-# Global settings
+# -----------------------------------------------------------------------------
+# General behaviour
+# -----------------------------------------------------------------------------
# Keyboard moves and resizes use this many pixels per step.
set step 5
@@ -12,9 +14,8 @@ set step 5
# disable menu key repetition.
set menu.repeat_keys Up,Down
-# Set the focus policy -- can be `sloppy`, or `click`. Note that `sloppy`
-# does not imply root window focus, and perhaps this should be fixed, or
-# renamed to `follows-mouse`?
+# Focus policy: "click" focuses on click; "sloppy" focuses as the pointer
+# enters a window. Sloppy focus does not focus the root window.
set focus sloppy
# Snap a moving window when it comes within this many pixels of an edge.
@@ -25,124 +26,203 @@ set snap_distance 12
# cascade when no unobstructed position can contain the complete frame.
set placement undermouse
+# Raise a window when it receives focus. Set false to preserve stacking.
+set raise_on_focus true
+
+# Cursor theme and size default to XCURSOR_THEME and XCURSOR_SIZE when those
+# variables are set, otherwise "default" and 24. Changes apply immediately
+# to River and CoW-owned cursors, and to applications subsequently launched
+# by CoW.
+# set cursor.theme Adwaita
+# set cursor.size 48
+
# Hide the pointer after this many milliseconds without input. Zero disables
# pointer hiding.
set cursor.hide_timeout 4000
-# Reserve an area on the screen. Can be reserved.{top, bottom, left, right}
+# -----------------------------------------------------------------------------
+# Outputs and backgrounds
+# -----------------------------------------------------------------------------
+
+# Reserve space which ordinary windows will not cover. The four keys are
+# reserved.top, reserved.right, reserved.bottom, and reserved.left. Match the
+# value to your panel's size, or set it to 0 when no reservation is needed.
+#
+# Note that applications such as waybar are already in a reserved space, which
+# CoW honours, so there's no need to set this option.
+#
set reserved.top 55
set reserved.left 10
set reserved.right 10
set reserved.bottom 10
-# Default decoration profile.
-decor -d default border.width 5
+# The base background colour is shared by all outputs.
+# Colours accept 0xRRGGBB or 0xRRGGBBAA; the final byte is opacity.
+set output.colour.background 0x282828
+
+# Background images may be PNG, SVG, or XPM. They tile over the base colour,
+# so transparent images can be combined with any colour. A suffix selects a
+# particular output; "none" disables the image on that output.
+#
+# set output.image.background cow-default-wallpaper.png
+# set output.colour.background.DP-1 0x828282
+# set output.image.background.DP-1 ~/pictures/wallpaper-tile.png
+# set output.image.background.eDP-1 none
+
+# -----------------------------------------------------------------------------
+# Desks and virtual pages
+# -----------------------------------------------------------------------------
+
+# Desk policy: "global" makes every output show the same desk; "per-output"
+# lets each output switch desks independently. The built-in default is global.
+set desktop-configuration per-output
+
+# Each desk can be larger than the output. A 1x1 grid disables paging; this
+# 3x3 example is navigated with scroll bindings or cursor-at-edge scrolling.
+set desktop_size 1 1
+
+# cow creates ten desks named 0 through 9. These commands show how to choose
+# a different count or assign names (cowbar -n displays names).
+# set desks.count 5
+# desk-name 0 main
+
+# Page changes are instantaneous by default. Enable both settings for a
+# smooth transition and choose its duration in milliseconds.
+# set page_scroll_animate true
+# set page_scroll_ms 200
+
+# With edge scrolling enabled, holding the pointer at a usable screen edge
+# changes page after this delay. Set edge_scroll false if bindings alone are
+# preferable. Edges at the boundary of the page grid do nothing.
+set edge_scroll true
+set edge_scroll_delay_ms 300
+
+# At an edge-scrolled page boundary, a settled window belongs to the page
+# containing its content origin. Use "overlap" to keep every intersecting
+# part visible when a window spans that boundary.
+set page_visibility origin
+
+# Keep interactive moves within the output under the pointer. Use
+# "all_outputs" to move freely within the bounding area of every output, or
+# "none" to disable boundary clamping. Edge snapping remains enabled.
+set clamp_mode output
+
+# -----------------------------------------------------------------------------
+# Default window decoration
+# -----------------------------------------------------------------------------
+
+# A decor profile is defined one property at a time, then applied with
+# `decor -a`. Applying it globally also makes it the profile used by future
+# windows. Keep baseline settings in one profile: rules should normally be
+# reserved for deliberate per-window or per-desk overlays.
+
+# Frame geometry and titlebar.
+decor -d default border.width 5
decor -d default border.style fvwm
# decor -d default border.corner_length 20
+decor -d default titlebar.enabled true
decor -d default titlebar.height 22
# decor -d default titlebar.position top
decor -d default titlebar.font 'GoMono Nerd Font Mono 10'
-decor -d default icon.enabled true
-decor -d default icon.size 32
-# icon.image defaults to CoW's installed icon.
-# decor -d default icon.background 0x465457
-# decor -d default icon.foreground 0xFFFFFF
-# decor -d default icon.title_relief true
-decor -d default titlebar.enabled true
+
+# Colours use 0xRRGGBB. A general edge value is inherited by each individual
+# edge or corner unless a more specific property overrides it. This example
+# gives focused edges different colours and uses one grey for the whole
+# unfocused frame. For a uniform focused frame, replace the eight
+# border.active.* lines with, for example:
+#
+# decor -d default border.active 0x3434E0
+# decor -d default border.active.n 0xE50000
+# decor -d default border.active.s 0xC4D30D
+
+decor -d default border.style fvwm
+decor -d default border.active.image none
+decor -d default border.inactive.image none
+decor -d default border.active.gradient HGradient 0x458588 0x83a598
+decor -d default border.inactive.gradient HGradient 0xa89984 0xebdbb2
+decor -d default titlebar.active_gradient HGradient 0x458588 0x83a598
+decor -d default titlebar.inactive_gradient HGradient 0xa89984 0xebdbb2
+decor -d default container.tab.active_gradient HGradient 0x458588 0x83a598
+decor -d default container.tab.inactive_gradient HGradient 0xa89984 0xebdbb2
+
+# Titlebar buttons: odd numbers are placed on the left and even numbers on the
+# right. Button actions are configured with bind-decoration below.
decor -d default titlebar.button.1.vector 5 25x40@1 25x60@1 75x60@0 75x40@0 25x40@1
decor -d default titlebar.button.2.vector 4 50x75@1 25x25@1 75x25@1 50x75@0
decor -d default titlebar.button.0.vector 4 50x25@1 75x75@0 25x75@0 50x25@1
-decor -a default
-# Titlebar buttons 0, 1, and 2 maximise, close, and iconify respectively.
-#bind-decoration 0 window-maximize -T
-#bind-decoration 1 winops -c
-#bind-decoration 2 winops -i
+# Iconified windows use the application's desktop-entry icon. Set icon.image
+# to a PNG/SVG/XPM path to force one image, or to "none" for no image.
+decor -d default icon.enabled true
+decor -d default icon.size 32
+decor -d default icon.image auto
+# decor -d default icon.background 0x828282
+# decor -d default icon.foreground 0xFFFFFF
+# decor -d default icon.title_relief false
-# Example overrides (commented out):
-#bind-decoration titlebar window-maximize -m # left-click maximises
-#bind-decoration -2 NE winops -c # NE double-click closes
-#bind-decoration -2 0 window-maximize -m # button 0 double-click
+# Container tabs inherit suitable colours from the titlebar by default. The
+# following overrides demonstrate independent inactive-tab styling. Remove
+# them to retain the inherited colours, or enable the optional active values.
+# decor -d default container.tab.active_colour 0x3434E0
+# decor -d default container.tab.fg_active 0xFFFFFF
+# decor -d default container.tab.inactive_colour 0x3434E0
+# decor -d default container.tab.fg_inactive 0x000000
+# decor -d default container.tab.sunken true
-# Theme packs can define decor profiles in separate files, with image paths
-# relative to that theme file. For example:
-#
-# include ~/.config/cow/themes/steel/theme.conf
-# decor -a steel
-#
-# See examples/themes/steel for a theme which uses SVG images for borders,
-# titlebars, tabs, and a titlebar button.
+# Optional squeezed titlebar. "natural" follows the title and button width;
+# "fixed" uses titlebar.squeeze.width. Justification may be left, centre, or
+# right. The unused part of the titlebar strip remains transparent.
+# decor -d default titlebar.squeeze natural
+# decor -d default titlebar.squeeze.justify left
+# decor -d default titlebar.squeeze.width 300
-# Container tab strip styling (optional overrides).
-#
-# By default, active tabs use the titlebar's base colour and inactive tabs
-# use the darkened (sunken) variant, with the titlebar's fg colour for all
-# labels so that text is readable regardless of background darkness.
-#
-# Uncomment and adjust to use distinct colours per-tab state:
-# container.tab.active_colour 0x3434E0
-# container.tab.fg_active 0xFFFFFF
-# Uncomment to restore the classic sunken bevel on inactive tabs:
-# container.tab.sunken true
+# Optional gradients. Use "none" to restore a solid colour. Images are
+# painted over gradients, so clear the corresponding image while experimenting.
+# decor -d default border.active.image none
+# decor -d default border.inactive.image none
+# decor -d default border.active.gradient HGradient 0x0044CC 0xFF3030
+# decor -d default border.inactive.gradient HGradient 0x203050 0x804040
+# decor -d default titlebar.active_gradient HGradient 0x0044CC 0xFF3030
+# decor -d default titlebar.inactive_gradient HGradient 0x203050 0x804040
+# decor -d default container.tab.active_gradient HGradient 0x607080 0xC0CCD0
-# Squeeze Titlebars.
-#
-# Similar to what CTWM used to allow, a squeeze titlebar is one whose length
-# is shortened to match the window title length. The remaining space is not
-# part of the window.
-#
-# For example:
-#
-#titlebar.squeeze natural
-#titlebar.squeeze.justify left
-#
-# Other justify options are right, centre
-# titlebar.squeeze fixed can be used as well to give a slightly larger
-# titlebar.
+# Apply the completed profile globally and make it the default for new windows.
+# When editing live, defining a property only changes the stored profile; send
+# `moocow decor -a default` afterwards to make the changes visible.
+decor -a default
-# The colour to use for the background (globally across all outputs).
-set output.colour.background 0x3B05A6
+# To use a theme pack instead, include it and apply the profile it defines.
+# The last global `decor -a` command wins. Relative image paths are resolved
+# from the theme file. See examples/themes/ for the supplied themes.
+# include ~/.config/cow/themes/steel/theme.conf
+# decor -a steel
-# Default window decoration (applies to all windows).
-#
-# Note that the colour options are still in hex, but are prefixed with `0x` to
-# disambiguate them from comments.
-#
-# Here. the window is styled by gicing each border a different colour, and the
-# handles (corners) a different colour as well.
-#
-# Inactive windows all have a grey (0xCDC9C9) colour. Note as well that
-# specifying the colour for `border.inactive` oe `border.active` in this way
-# sets the colour for all components, and are inherited. For example:
+# -----------------------------------------------------------------------------
+# Icon placement
+# -----------------------------------------------------------------------------
#
-# Set the default colour of inactive windows:
-#
-# border.inactive = 0xCDC9C9
-# border.inactive.n = 0xFF00FF
-#
-# This would set the all components of the inactive window to grey, and style
-# just the north border as magenta,
+# Automatic placement starts at the bottom-left, fills right, and wraps up.
+# This alternative fills down the right-hand side instead:
+# icon-placement box full
+# icon-placement fill down left
+# icon-placement compact false
-decor -d global-on-map border.style fvwm
-decor -d global-on-map border.active.image none
-decor -d global-on-map border.inactive.image none
-decor -d global-on-map border.active.gradient HGradient 0x458588 0x83a598
-decor -d global-on-map border.inactive.gradient HGradient 0xa89984 0xebdbb2
-decor -d global-on-map titlebar.active_gradient HGradient 0x458588 0x83a598
-decor -d global-on-map titlebar.inactive_gradient HGradient 0xa89984 0xebdbb2
-decor -d global-on-map container.tab.active_gradient HGradient 0x458588 0x83a598
-decor -d global-on-map container.tab.inactive_gradient HGradient 0xa89984 0xebdbb2
+# Output-specific settings inherit unspecified global placement properties.
+# `@2` selects output number 2; an output name may be used instead.
+# icon-placement -o @2 box 96x900-0+0
+# icon-placement -o @2 grid 8 8
-rule -g -Ton-map -nglobal-on-map decor -a global-on-map
+# -----------------------------------------------------------------------------
+# Decoration overlays and rules
+# -----------------------------------------------------------------------------
-# Module chrome example. Sparse decor profiles are applied as overlays, so
-# this keeps the active theme colours/images and only removes cowiconman's
-# frame chrome.
-#
-# decor -d cowiconman-chrome border.width 0
-# decor -d cowiconman-chrome border.handles false
-# decor -d cowiconman-chrome titlebar.enabled false
-# rule -g -Ton-map -ncowiconman-chrome -s %cowiconman decor -a cowiconman-chrome
+# Profiles applied by rules are sparse overlays. This example can remove the
+# frame from cowiconman without replacing colours or images from the active
+# global theme. Uncomment all four lines to enable it.
+# decor -d nodecor border.width 0
+# decor -d nodecor border.handles false
+# decor -d nodecor titlebar.enabled false
+# rule -g -T on-map -n nodecor -s %cowiconman decor -a nodecor
# Remove cowbuttons' own window decors using a cow rule:
@@ -156,102 +236,122 @@ decor -d cowpager-nodecor border.handles false
decor -d cowpager-nodecor titlebar.enabled false
rule -g -Ton-map -ncowpager-chrome -s %cowpager decor -a cowpager-nodecor
+# This optional example tints desks 1 and 2. `-t :1` means desk 1 on any
+# output. An on-desk rule is applied to every window on the desk whenever that
+# desk becomes current or a view maps onto it. Uncomment the definitions and
+# rules together.
+# decor -d per-1 titlebar.active_colour 0xFF8C00
+# decor -d per-1 titlebar.active_gradient none
+# decor -d per-1 titlebar.inactive_colour 0xB28E4C
+# decor -d per-1 border.inactive 0xB28E4C
+# decor -d per-2 titlebar.active_colour 0xFFD700
+# decor -d per-2 titlebar.active_gradient none
+# rule -T on-desk -t :1 -n per-1 decor -a per-1
+# rule -T on-desk -t :2 -n per-2 decor -a per-2
-# The restart rule allows for general cleanup. The `exec` command will always
-# run in this config on (re)start, so not doing things such as killing conky
-# or waybar will mean more than one instance will run.
+# On restart, stop existing panel and status-program processes before startup
+# commands create replacements. Keep this list in sync with programs started
+# here or by your compositor's startup file.
# rule -g -T on-restart -n cleanup \
# exec killall waybar \; \
# exec killall conky \; \
# exec killall pasystray
-# Set the desk policy. Can be "global" where all screens share the same
-# desktop, or "per-output" where desks are unique to their outputs and each
-# output can be changed independently from one another.
-#
-# The default is `global`
-set desktop-configuration per-output
+rule -g -n mpv -T on-map -s %mpv script {
+ winops -sS
+ winops -L =top
+ window-resize -w 640 -h 360
+ window-move -x 1265 -y 705
+ }
-# Virtual page grid. Anything greater than 1x1 enables paging; each desk
-# is then a `cols x rows` grid of pages navigated with the `scroll` command
-# (and optionally with edge_scroll for cursor-at-edge auto-pan).
-set desktop_size 1 1
+rule -g -T on-map -n cowbuttons script {
+ if self.title == "cowbuttons:Status" and self.output == "HDMI-A-1"{
+ winops -sS
+ winops -C on
+ window-move -x 1555 -y 5
+ }
+ if self.title == "cowbuttons:Status" and self.output == "eDP-1"{
+ winops -sS
+ winops -C on
+ window-move -x 3475 -y 5
+ }
+ if self.title == "cowbuttons:Clock" and self.output == "HDMI-A-1"{
+ winops -sS
+ winops -C on
+ window-move -x 825 -y 5
+ }
+ if self.title == "cowbuttons:Clock" and self.output == "eDP-1"{
+ winops -sS
+ winops -C on
+ window-move -x 2745 -y 5
+ }
+}
-# Desktop management: cow defaults to setting up ten desks, which have a name
-# of 0..9 respectively.
-#
-# Both the name and the number of desktops available can be altered. For
-# example, to only have five desks, set the `desks.count` settings:
-#
-# set desks.count 5
-#
-# Without any further adjustment, cow would name those desks 0..4
-# respectively.
-#
-# To change a name of a desk, use the `desk-name` command. For example, to
-# name the first desk to 'main', use:
-#
-# desk-name 0 main
-#
-# This would set desk 0's name to 'main'.
-#
-# cowbar(1) can be told to use names explicitly rather than a desk number, by
-# using its `-n` option.
+rule -g -T on-map -n cowiconman -s /cowiconman-/ script {
+ winops -sS
+ winops -C on
+ window-move -x 500 -y 1040
+ }
-# Smooth page transition animation (default: instant cut)
-#set page_scroll_animate true
-#set page_scroll_ms 200
+rule -g -T on-map -n cowpager -s /cowpager:/ script {
+ if self.output == "HDMI-A-1"{
+ winops -sS
+ winops -C on
+ window-move -x 15 -y 5
+ }
+ if self.output == "eDP-1"{
+ winops -sS
+ winops -C on
+ window-move -x 1935 -y 5
+ }
+}
-# Edge scroll: dwell at a screen edge to switch page (default: off).
-# The page switches once the cursor has been at the edge for
-# edge_scroll_delay_ms milliseconds. No-op directions (already at
-# the page-grid boundary) don't arm.
-#
-# If this is disabled, it's recommended to setup key bindings to switch pages.
-set edge_scroll true
-set edge_scroll_delay_ms 300
+# -----------------------------------------------------------------------------
+# Keyboard bindings
+# -----------------------------------------------------------------------------
-# Keep interactive moves within the output under the pointer. Use
-# "all_outputs" to move freely within the bounding area of every output, or
-# "none" to disable boundary clamping. Edge snapping remains enabled.
-set clamp_mode output
+# Generate direct desk bindings from output @1's canonical desk list. Number
+# keys cover desks 0 through 9; desks beyond that remain available through the
+# next/previous bindings and menus. The top-level script handles config
+# reloads, when outputs already exist.
+script {
+ for d in (desks where d.output_number == 1 and d.nr <= 9) {
+ bind "L+#{d.nr}" desk -d #{d.nr}
+ bind "LS+#{d.nr}" window-move -k #{d.nr}
+ }
+}
-# Raise on focus: raise window when focused (default: on).
-set raise_on_focus true
+# On initial startup, install the bindings after outputs and desks exist.
+rule -g -T on-outputs-changed -n desk-number-bindings script {
+ bind -d "L+[0-9]"
+ bind -d "LS+[0-9]"
+ for d in (desks where d.output_number == 1 and d.nr <= 9) {
+ bind "L+#{d.nr}" desk -d #{d.nr}
+ bind "LS+#{d.nr}" window-move -k #{d.nr}
+ }
+}
-# Desk switching.
-bind L+0 desk -d 0
-bind L+1 desk -d 1
-bind L+2 desk -d 2
-bind L+3 desk -d 3
-bind L+4 desk -d 4
-bind L+5 desk -d 5
-bind L+6 desk -d 6
-bind L+7 desk -d 7
-bind L+8 desk -d 8
-bind L+9 desk -d 9
+# Rebuild after `moocow set desks.count N` changes the live desk sets.
+rule -g -T on-desks-changed -n desk-number-bindings-on-resize script {
+ bind -d "L+[0-9]"
+ bind -d "LS+[0-9]"
+ for d in (desks where d.output_number == 1 and d.nr <= 9) {
+ bind "L+#{d.nr}" desk -d #{d.nr}
+ bind "LS+#{d.nr}" window-move -k #{d.nr}
+ }
+}
+
+# Cycle through every configured desk, including desks without a number key.
bind L+bracketright desk -n
bind L+bracketleft desk -p
-# Send window to desk
-bind LS+0 window-move -k 0
-bind LS+1 window-move -k 1
-bind LS+2 window-move -k 2
-bind LS+3 window-move -k 3
-bind LS+4 window-move -k 4
-bind LS+5 window-move -k 5
-bind LS+6 window-move -k 6
-bind LS+7 window-move -k 7
-bind LS+8 window-move -k 8
-bind LS+9 window-move -k 9
-
# Desk collection. This will show windows on the specified desk (the current
# output is implied). When this happens, these "collected" windows can be
-# moved resized, etc. When the desk is uncollected (this command acts as a
+# moved, resized, etc. When the desk is uncollected (this command acts as a
# toggle), the windows go back to their original desk, and their geometries
# are restored.
#
-# This gives a handy-way of glancing at other windows without having to make
+# This gives a handy way of glancing at other windows without having to make
# them sticky, for example.
bind LA+0 desk -c 0
bind LA+1 desk -c 1
@@ -279,42 +379,53 @@ bind C+i winops -i
# Full screen a window regardless of reserved areas
bind L+f window-maximize -T -R
-# Focus windows, next/prev.
-bind A+Tab focus -nw -F 'self.current_output and self.current_page'
+# CirculateSkip removes matching windows from next/previous focus circulation
+# while leaving explicit focus and mouse focus available.
+# rule -g -T on-map -n skip-cowpager -s %cowpager winops -C on
+# rule -g -T on-map -n skip-cowbar -s %cowbar winops -C on
+
+# Focus windows, next/prev. -F adds a DSL predicate to circulation.
+# Examples:
+# focus -nw -F 'self.current_desk'
+# focus -nw -F 'self.current_output'
+# focus -nw -F 'self.current_output and self.current_page'
+bind A+Tab focus -nw -F 'self.current_output and self.current_page'
bind AS+Tab focus -pw -F 'self.current_output and self.current_page'
-# Move (see the `step` setting) -r after bind is for auto repeat
+# Move (see the `step` setting).
bind -r LS+Up window-move -w -d up
bind -r LS+Down window-move -w -d down
bind -r LS+Left window-move -w -d left
bind -r LS+Right window-move -w -d right
-# Move (snap to nearest edge / cross monitor)
+# Move (snap to the nearest edge or cross a monitor boundary).
bind L+Up window-move -nw -d up
bind L+Down window-move -nw -d down
bind L+Left window-move -nw -d left
bind L+Right window-move -nw -d right
# Centre the window and focus.
-bind L+c script {
- window-move -c
- focus -w
-}
+ bind L+c script {
+ window-move -c
+ focus -w
+ }
-# Resize
-bind LA+Up window-resize -s -d up
-bind LAS+Up window-resize -g -d up
-bind LA+Down window-resize -g -d down
-bind LAS+Down window-resize -s -d down
-bind LA+Left window-resize -s -d left
-bind LAS+Left window-resize -g -d left
-bind LA+Right window-resize -g -d right
-bind LAS+Right window-resize -s -d right
+# Resize. Without Shift, move the north/west edge; with Shift, move the
+# south/east edge.
+bind LA+Up window-resize -g -d up
+bind LA+Down window-resize -s -d up
+bind LAS+Up window-resize -s -d down
+bind LAS+Down window-resize -g -d down
+bind LA+Left window-resize -g -d left
+bind LA+Right window-resize -s -d left
+bind LAS+Left window-resize -s -d right
+bind LAS+Right window-resize -g -d right
-# Session
+# End the session.
bind LCA+q quit
-# Custom bindings to run commands.
+# Run external commands. Replace these examples with the terminal, launcher,
+# and power-management commands available on your system.
bind L+Return exec foot
bind L+d exec fuzzel
@@ -361,7 +472,11 @@ bind LS+b script {
}
}
-# Mouse bindings
+# -----------------------------------------------------------------------------
+# Mouse and decoration bindings
+# -----------------------------------------------------------------------------
+
+# Hold the chosen modifier while dragging anywhere in a window.
mouse L+left window-move
mouse L+right window-resize
# Super+middle-drag: drag a window's titlebar onto another to containerise
@@ -396,11 +511,21 @@ bind-decoration SW window-resize -e sw
bind-decoration titlebar window-move
bind-decoration -2 titlebar window-shade -d titlebar
+# Titlebar buttons 0, 1, and 2 maximise, close, and iconify respectively.
+bind-decoration 0 window-maximize -T
+bind-decoration 1 winops -c
+bind-decoration 2 winops -i
+
# Example overrides (commented out):
#bind-decoration titlebar window-maximize -m # left-click maximises
#bind-decoration -2 NE winops -c # NE double-click closes
+#bind-decoration -2 0 window-maximize -m # button 0 double-click
-# Container bindings
+# -----------------------------------------------------------------------------
+# Window containers
+# -----------------------------------------------------------------------------
+
+# Keyboard bindings for tabbed window containers.
# Super+G: group focused window with the next window in stacking order.
# Works without a mouse -- useful in VNC or keyboard-only environments.
bind L+g window-container -a
@@ -413,62 +538,42 @@ bind LS+Tab window-container -p
bind LC+Tab window-container -N
bind LCS+Tab window-container -P
-# Rules
+# -----------------------------------------------------------------------------
+# Page navigation
+# -----------------------------------------------------------------------------
-# Make mpv appear on top and become sticky
-rule -g -n mpv -T on-map -s %mpv script {
- winops -sS
- winops -L =top
- window-resize -w 640 -h 360
- window-move -x 1265 -y 705
-}
+# These bindings are only useful when desktop_size is greater than 1x1. The
+# `scroll` command pans the desk viewport by whole pages (with -d / -n / -P)
+# or by arbitrary sub-page offsets (a bare "H V" percentage, "-p H V" pixels,
+# or an interactive "-r" drag bound to a mouse button). See `list-commands`
+# for the full command surface.
+#
+# Super+Ctrl+Right/Left/Down/Up: jump one page in that direction
+# bind LC+Right scroll -d right
+# bind LC+Left scroll -d left
+# bind LC+Down scroll -d down
+# bind LC+Up scroll -d up
-rule -g -T on-map -n cowbuttons script {
- if self.title == "cowbuttons:Status" and self.output == "HDMI-A-1"{
- winops -sS
- winops -C on
- window-move -x 1555 -y 5
- }
- if self.title == "cowbuttons:Status" and self.output == "eDP-1"{
- winops -sS
- winops -C on
- window-move -x 3475 -y 5
- }
- if self.title == "cowbuttons:Clock" and self.output == "HDMI-A-1"{
- winops -sS
- winops -C on
- window-move -x 825 -y 5
- }
- if self.title == "cowbuttons:Clock" and self.output == "eDP-1"{
- winops -sS
- winops -C on
- window-move -x 2745 -y 5
- }
-}
+# Super+Ctrl+n / Super+Ctrl+p: next / previous page (with wrap)
+# bind LC+n scroll -n
+# bind LC+p scroll -P
-rule -g -T on-map -n cowiconman -s /cowiconman-/ script {
- winops -sS
- winops -C on
- window-move -x 500 -y 1040
- }
+# Ctrl+Meta+Button1: grab and drag the desk viewport
+# mouse CM+Left scroll -r
-rule -g -T on-map -n cowpager -s /cowpager:/ script {
- if self.output == "HDMI-A-1"{
- winops -sS
- winops -C on
- window-move -x 15 -y 5
- }
- if self.output == "eDP-1"{
- winops -sS
- winops -C on
- window-move -x 1935 -y 5
- }
-}
+# -----------------------------------------------------------------------------
+# Startup programs
+# -----------------------------------------------------------------------------
+
+# These commands run each time cow starts. Keep only programs installed on
+# your system. Programs which do not replace an existing instance should also
+# be added to the on-restart cleanup rule above.
-# Clipboard persistence (retain clipboard content after an app closes):
-#exec wl-clip-persist --clipboard regular
+exec sh "$HOME/.config/cow/scripts/after-start.sh"
+# -----------------------------------------------------------------------------
# Menus
+# -----------------------------------------------------------------------------
#
# Define menus with menu-add, then bind them to mouse buttons or keys.
# Selectable items can use `menu-add -i terminal.svg ...`. Relative icon
@@ -504,14 +609,14 @@ menu-style automatic.hotkeys true
# menu-style -m SendToDesk title.fg 0xffffff
# menu-style -m SendToDesk separator 0xa38ab3
# menu-style -m SendToDesk border.colour 0x4b2c5c
-
+#
# menu-style -m WindowOps bg 0xe7d8d2
# menu-style -m WindowOps fg 0x321915
# menu-style -m WindowOps title.bg 0x8b3a2f
# menu-style -m WindowOps title.fg 0xffffff
# menu-style -m WindowOps separator 0xb78378
# menu-style -m WindowOps border.colour 0x57231d
-
+#
# menu-style -m RootMenu bg 0xd7e4e2
# menu-style -m RootMenu fg 0x102b29
# menu-style -m RootMenu title.bg 0x0d7068
@@ -519,25 +624,42 @@ menu-style automatic.hotkeys true
# menu-style -m RootMenu separator 0x72aaa5
# menu-style -m RootMenu border.colour 0x084b46
-# Sub-menu: send window to a desk.
-menu-add SendToDesk "Send to Desk" title
-menu-add SendToDesk "Desk 0" "window-move -k 0"
-menu-add SendToDesk "Desk 1" "window-move -k 1"
-menu-add SendToDesk "Desk 2" "window-move -k 2"
-menu-add SendToDesk "Desk 3" "window-move -k 3"
-menu-add SendToDesk "Desk 4" "window-move -k 4"
-menu-add SendToDesk "Desk 5" "window-move -k 5"
-menu-add SendToDesk "Desk 6" "window-move -k 6"
-menu-add SendToDesk "Desk 7" "window-move -k 7"
-menu-add SendToDesk "Desk 8" "window-move -k 8"
-menu-add SendToDesk "Desk 9" "window-move -k 9"
+# Sub-menu: send a window to a desk. Every output has the configured number
+# of desks, so use output @1 as the canonical list to avoid duplicate entries
+# with desktop-configuration per-output. The top-level script handles config
+# reloads, when outputs already exist.
+menu-add SendToDesk "Send to Desk" title
+script {
+ for d in (desks where d.output_number == 1) {
+ menu-add SendToDesk "Desk #{d.nr}" "window-move -k #{d.nr}"
+ }
+}
+
+# On initial startup the config is read before outputs exist. Build the menu
+# once their desk sets are available, and rebuild it after output changes.
+rule -g -T on-outputs-changed -n send-to-desk-menu script {
+ menu-clear SendToDesk
+ menu-add SendToDesk "Send to Desk" title
+ for d in (desks where d.output_number == 1) {
+ menu-add SendToDesk "Desk #{d.nr}" "window-move -k #{d.nr}"
+ }
+}
+
+# Keep the menu in sync with runtime changes to desks.count as well.
+rule -g -T on-desks-changed -n send-to-desk-menu-on-resize script {
+ menu-clear SendToDesk
+ menu-add SendToDesk "Send to Desk" title
+ for d in (desks where d.output_number == 1) {
+ menu-add SendToDesk "Desk #{d.nr}" "window-move -k #{d.nr}"
+ }
+}
# Window operations menu.
menu-add WindowOps "Window" title
menu-add WindowOps "Move" "window-move"
menu-add WindowOps "Resize" "window-resize"
menu-add WindowOps "Maximise" "window-maximize"
-menu-add WindowOps "Shade North" "window-shade -d n"
+menu-add WindowOps "Shade" "window-shade -d titlebar"
menu-add WindowOps - -
menu-add WindowOps "Send To Desk" "popup SendToDesk"
menu-add WindowOps - -
@@ -548,6 +670,7 @@ menu-add WindowOps "Close" "winops -c"
menu-add RootMenu "CoW" title
# With ~/.config/cow/icons/terminal.svg installed, the following may instead
# be written as: menu-add -i terminal.svg RootMenu "XTerm" "exec xterm"
+# menu-add RootMenu "XTerm" "exec xterm"
menu-add -i foot.svg RootMenu "Terminal" "exec foot"
menu-add RootMenu - -
menu-add RootMenu "Window Ops" "popup-pick WindowOps"
@@ -566,5 +689,3 @@ mouse I:0+right "menu-show WindowOps"
# If a window menu is not invoked from a known window context, use
# pick-window so the selected menu action targets the picked window.
# bind M+w "pick-window menu-show WindowOps"
-
-exec sh "$HOME/.config/cow/scripts/after-start.sh"