Skip to main content
GUI events are emitted by WezTerm’s graphical user interface layer during application startup and attachment to domains. These events allow you to customize the initial state of your terminal environment.

gui-startup

Since: 20220624-141144-bd1b7c5d Emitted once when the GUI server starts up (when running wezterm start).

Timing

  • Fires before any default program is started
  • Fires before gui-attached event
  • Does NOT fire for wezterm connect invocations
  • If this event creates panes, they take precedence over default program configuration

Event Signature

wezterm.on('gui-startup', function(cmd)
  -- cmd is an optional SpawnCommand object
  -- representing any arguments passed to `wezterm start`
end)
cmd
SpawnCommand | nil
Optional spawn command from wezterm start arguments. Added in version 20220807-113146-c2fee766.

Return Value

No return value expected. This is a fire-and-forget event.

Examples

Split Window into Thirds

local wezterm = require 'wezterm'
local mux = wezterm.mux
local config = {}

wezterm.on('gui-startup', function(cmd)
  local tab, pane, window = mux.spawn_window(cmd or {})
  -- Create a split occupying the right 1/3 of the screen
  pane:split { size = 0.3 }
  -- Create another split in the remaining 2/3
  pane:split { size = 0.5 }
end)

return config

Maximize on Startup

wezterm.on('gui-startup', function(cmd)
  local tab, pane, window = mux.spawn_window(cmd or {})
  window:gui_window():maximize()
end)

Multiple Workspaces

wezterm.on('gui-startup', function(cmd)
  local args = {}
  if cmd then
    args = cmd.args
  end

  -- Coding workspace
  local project_dir = wezterm.home_dir .. '/wezterm'
  local tab, build_pane, window = mux.spawn_window {
    workspace = 'coding',
    cwd = project_dir,
    args = args,
  }
  local editor_pane = build_pane:split {
    direction = 'Top',
    size = 0.6,
    cwd = project_dir,
  }
  build_pane:send_text 'cargo build\n'

  -- Automation workspace
  local tab, pane, window = mux.spawn_window {
    workspace = 'automation',
    args = { 'ssh', 'vault' },
  }

  -- Start in coding workspace
  mux.set_active_workspace 'coding'
end)

Use Cases

  • Setting up development environments with specific layouts
  • Creating workspace-based configurations
  • Maximizing or positioning windows on startup
  • Auto-starting specific commands or shells

gui-attached

Since: 20230320-124340-559cb7b0 Emitted when the GUI attaches to a domain after startup.

Timing

  • Fires AFTER gui-startup event
  • Fires when using wezterm connect DOMAIN or wezterm start --domain DOMAIN
  • If no domain is specified, the default domain is passed
  • gui-startup does NOT fire when using wezterm connect DOMAIN or wezterm start --domain DOMAIN --attach

Event Signature

wezterm.on('gui-attached', function(domain)
  -- domain is a MuxDomain object
end)
domain
MuxDomain
The multiplexer domain that was attached. Provides information about the domain type and configuration.

Return Value

No return value expected.

Examples

Maximize All Windows on Attach

local wezterm = require 'wezterm'
local mux = wezterm.mux

wezterm.on('gui-attached', function(domain)
  -- Maximize all displayed windows on startup
  local workspace = mux.get_active_workspace()
  for _, window in ipairs(mux.all_windows()) do
    if window:get_workspace() == workspace then
      window:gui_window():maximize()
    end
  end
end)

local config = wezterm.config_builder()
return config

Domain-Specific Setup

wezterm.on('gui-attached', function(domain)
  local domain_name = domain:name()
  
  if domain_name == 'SSH:production' then
    -- Set visual indicator for production
    for _, window in ipairs(mux.all_windows()) do
      local overrides = window:get_config_overrides() or {}
      overrides.color_scheme = 'Red Alert'
      window:set_config_overrides(overrides)
    end
  end
end)

Log Domain Information

wezterm.on('gui-attached', function(domain)
  wezterm.log_info('Attached to domain: ' .. domain:name())
  wezterm.log_info('Domain state: ' .. domain:state())
end)

Use Cases

  • Maximizing windows when connecting to remote domains
  • Setting domain-specific visual themes or configurations
  • Logging connection information
  • Adjusting workspace layouts based on domain type

Comparison: gui-startup vs gui-attached

-- Fires when running: wezterm start
wezterm.on('gui-startup', function(cmd)
  -- Setup initial layout
end)

-- Followed by gui-attached
wezterm.on('gui-attached', function(domain)
  -- Additional setup after domain attachment
end)

Common Patterns

Project-Specific Layouts

local projects = {
  web = {
    dir = wezterm.home_dir .. '/projects/web',
    splits = { 'npm run dev', 'git status' }
  },
  api = {
    dir = wezterm.home_dir .. '/projects/api',
    splits = { 'docker-compose up', 'npm test -- --watch' }
  }
}

wezterm.on('gui-startup', function(cmd)
  for name, project in pairs(projects) do
    local tab, pane, window = mux.spawn_window {
      workspace = name,
      cwd = project.dir,
    }
    
    for i, command in ipairs(project.splits) do
      if i > 1 then
        pane = pane:split { size = 0.5 }
      end
      pane:send_text(command .. '\n')
    end
  end
  
  mux.set_active_workspace 'web'
end)

Conditional Window Positioning

wezterm.on('gui-startup', function(cmd)
  local tab, pane, window = mux.spawn_window(cmd or {})
  local gui_window = window:gui_window()
  
  -- Get screen dimensions
  local screens = wezterm.gui.screens()
  local active_screen = screens.active
  
  if active_screen.width > 2560 then
    -- Ultra-wide monitor: position on right half
    gui_window:set_position(active_screen.width / 2, 0)
    gui_window:set_inner_size(active_screen.width / 2, active_screen.height)
  else
    -- Normal monitor: maximize
    gui_window:maximize()
  end
end)

See Also