cagebreak-socket(7)
π cagebreak-socket(7) π
okay so this is the <pink>cagebreak-socket(7)</pink> page from the Cagebreak Manual β the full vibe check on the Cagebreak socket, bestie β¨
π NAME π
cagebreak-socket β Cagebreak socket
π¦ SYNOPSIS π¦
ipc-socket-capable-tool $CAGEBREAK_SOCKET
β¨ DESCRIPTION β¨
The cagebreak socket is an ipc socket, no cap.
It's enabled when cagebreak is invoked with the -e flag. Slay.
The socket accepts cagebreak commands as input (peep cagebreak-config(5) for the whole tea). Events come back out as output, exactly as specified in this man page. Periodt.
π EVENTS π
Events have this general structure:
"cg-ipc"json object depending on the eventNULL
Here's an example of how it works when only is the command sent over the socket:
only
cg-ipc{"event_name":"fullscreen",
"tile_id":2,
"workspace":1,
"output":"eDP-1"}
This documentation describes the trigger for each event, the keys, and the data type of each event's values. You're gonna eat this up π
π background π
- Trigger:
backgroundcommand - JSON:
event_name:"background"old_bg: list of three floating point numbers denoting the old background in rgbnew_bg: list of three floating point numbers denoting the new background in rgb
background 0 1.0 0
cg-ipc{"event_name":"background",
"old_bg":[0.000000,1.000000,1.000000],
"new_bg":[0.000000,1.000000,0.000000]}
π close π
- Trigger:
closecommand - JSON:
event_name:"close"view_id: view id as an integertile_id: tile id as an integerview_pid: pid of the processworkspace: workspace number as an integeroutput: name of the output as a stringoutput_id: id of the output as an integer
close
cg-ipc{"event_name":"close",
"view_id":47,
"view_pid":30456,
"tile_id":47,
"workspace":1,
"output":"eDP-1",
"output_id":1}
π configure_input π
- Trigger:
inputcommand - JSON:
event_name:"configure_input"input: the input as a string, as percagebreak-config(5)
input * accel_profile flat
cg-ipc{"event_name":"configure_input","input":"*"}
π configure_message π
- Trigger:
configure_messagecommand - JSON:
event_name:"configure_message"
configure_message fg_color 1.0 1.0 0 0
cg-ipc{"event_name":"configure_message"}
π configure_output π
- Trigger:
outputcommand - JSON:
event_name:"configure_output"output: name of the output as a stringoutput_id: id of the output as an integer
output eDP-1 rotate 0
cg-ipc{"event_name":"configure_output","output":"eDP-1","output_id":1}
π cursor_switch_tile π
- Trigger: Cursor crosses the border between tiles
- JSON:
event_name:"cursor_switch_tile"old_output: name of the old output as a stringold_output_id: old output id as an integerold_tile: number of the old tile as an integernew_output: name of the new output as a stringnew_output_id: new output id as an integernew_tile: number of the new tile as an integer
# Cursor switches tile
cg-ipc{"event_name":"cursor_switch_tile",
"old_output":"eDP-1",
"old_output_id":1,
"old_tile":2,
"new_output":"eDP-1",
"new_output_id":1,
"new_tile":3}
π custom_event π
- Trigger: Cagebreak receives the
custom_eventcommand, either in the config file or via the IPC socket (seecagebreak-config(5)) - JSON:
event_name:"custom_event"message: The message passed to thecustom_eventcommand
custom_event Hello World!
cg-ipc{"event_name":"custom_event","message":"Hello World!"}
π cycle_outputs π
- Trigger:
nextscreenandprevscreencommands - JSON:
event_name:"cycle_outputs"old_output: old output name as stringold_output_id: old output id as an integernew_output: new output name as stringnew_output_id: new output id as an integerreverse:"0"ifnextscreenor"1"ifprevscreen
nextscreen
cg-ipc{"event_name":"cycle_outputs",
"old_output":"eDP-1",
"old_output_id":1,
"new_output":"HDMI-A-1",
"new_output_id":2,
"reverse":0}
π cycle_views π
- Trigger:
nextandprevcommands - JSON:
event_name:"cycle_views"old_view_id: old view id as an integerold_view_pid: pid of old viewnew_view_id: new view id as an intergernew_view_pid: pid of new viewtile_id: tile id as an integerworkspace: workspace number as an integeroutput: name of the output as a stringoutput_id: id of the output as an integer
next
cg-ipc{"event_name":"cycle_views",
"old_view_id":11,
"old_view_pid":32223,
"new_view_id":4,
"old_view_pid";53221,
"tile_id":13,
"workspace":1,
"output":"eDP-1",
"output_id":1}
π definekey π
- Trigger:
definekeycommand - JSON:
event_name:"definekey"modifiers: number denoting the modifier as described below0: no modifier1: shift2: alt3: ctrl4: logo key5: modifier 26: modifier 37: modifier 5
key: key as a numbercommand: command as a string β CAVEAT: This is an internal representation of commands which is not in one-to-one correspondance with the commands available in the config file. The differences are as follows:"cycle_tiles": represents any exchange command (e.g.exchangeright)"cycle_views": represents both thenextand theprevcommand"cycle_outputs": representsnextscreen,movetoprevscreenandprevscreencommands"resize_tile_vertical": representsresizedownandresizeupcommands"resize_tile_horizontal": representsresizeleftandresizerightcommands
definemode foo
cg-ipc{"event_name":"definemode","mode":"foo"}
definekey foo e only
cg-ipc{"event_name":"definekey","modifiers":0,"key":101,"command":"only"}
π definemode π
- Trigger:
definemodecommand - JSON:
event_name:"definemode"mode: name of mode as string
definemode foo
cg-ipc{"event_name":"definemode","mode":"foo"}
π destroy_output π
- Trigger: removal of an output
- JSON:
event_name:"destroy_output"output: name of the output as a stringoutput_id: id of the output as an integer
# remove output from the device
cg-ipc{"event_name":"destroy_output","output":"HDMI-A-1","output_id":2}
π dump π
- Trigger:
dumpcommand - JSON:
event_name:"dump"nws: number of workspaces as an integerbg_color: list of three floating point numbers denoting the new background in rgbviews_curr_id: id of the currently focussed view as an integertiles_curr_id: id of the currently focussed tile as in integercurr_output: current output as a stringdefault_mode: name of the default mode as a stringmodes: list of names of modes as stringsmessage_config: the current configuration of the cagebreak messagesfont: the font used to display the messagesdisplay_time: the duration in seconds that the cagebreak messages are displayedbg_color: list of four floating point numbers denoting the background color in rgbafg_color: list of four floating point numbers denoting the foreground color in rgbaanchor: the positioning of the messages on the screen (seecagebreak-config(5)for more information)
outputs: object of objects for each output- output name as string
priority: priority as peroutput prio <n>incagebreak-config(5)or defaultcoords: object of x and y coordinates of outputsize: object of width and height as integersrefresh_rate: refresh rate as floatpermanent: 0 if peripheral, 1 if permanentactive: 1 if the output is active, 0 if notcurr_workspace: current workspace as an integerworkspaces: list of objects for each workspaceviews: list of objects for each viewid: view id as an integerpid: pid of the process which opened the view as an integercoords: object of x and y coordinatestype:["xdg"|"xwayland"]
tiles: list of objects for all tilesid: tile id as an integercoords: object of x and y coordinatessize: object of width and heightview: view id as an integer
- output name as string
keyboards: object of objects for each keyboard group- keyboard name as a string
commands_enabled: 0 if keybindings are disabled for the keyboard, 1 otherwiserepeat_delay: repeat delay in milliseconds as an integerrepeat_rate: repeat rate in 1/sec as an integer
- keyboard name as a string
input_devices: object of objects for each keyboard- identifier for a keyboard as a string
is_virtual: 1 if virtual, 0 otherwisetype:[keyboard|pointer|switch]
- identifier for a keyboard as a string
cursor_coords: object of x and y coordinates
okay continuing the event tour β buckle up bestie, there's like sixteen of these and they're all lowkey iconic π
πΎ dump
Triggered by: the dump command β and yeah, she's the main character of the events, the way she just dumps the entire state of your world into one JSON blob π
dump
cg-ipc{"event_name":"dump","nws":1,
"bg_color":[0.000000,0.000000,0.000000],
"views_curr_id":80,
"tiles_curr_id":8,
"curr_output":"eDP-1",
"default_mode":"top",
"modes":["top","root","resize"],
"message_config": {"font": "pango:Monospace 10",
"display_time": 2,
"bg_color": [0.900000,0.850000,0.850000,1.000000],
"fg_color": [0.000000,0.000000,0.000000,1.000000],
"anchor": "top_right"
},"outputs": {"eDP-1": {
"priority": -1,
"coords": {"x":0,"y":0},
"size": {"width":2560,"height":1440},
"refresh_rate": 60.012000,
"permanent": 0,
"active": 1,
"curr_workspace": 0,
"workspaces": [{"views": [{
"id": 16,
"pid": 2505,
"coords": {"x":0,"y":0},
"type": "xwayland"
},{
"id": 72,
"pid": 11243,
"coords": {"x":0,"y":0},
"type": "xdg"
},{
"id": 56,
"pid": 6700,
"coords": {"x":1280,"y":0},
"type": "xdg"
}],"tiles": [{
"id": 6,
"coords": {"x":0,"y":0},
"size": {"width":1280,"height":1440},
"view": 78
},{
"id": 7,
"coords": {"x":1280,"y":0},
"size": {"width":1280,"height":1440},
"view": 42
}]}]
}}
,"keyboards": {"0:1:Power_Button": {
"commands_enabled": 1,
"repeat_delay": 600,
"repeat_rate": 25
}}
,"input_devices": {"6058:20564:ThinkPad_Extra_Buttons": {
"is_virtual": 0,
"type": "switch",
},"6058:20564:ThinkPad_Extra_Buttons": {
"is_virtual": 0,
"type": "keyboard",
},"2:10:TPPS/2_Elan_TrackPoint": {
"is_virtual": 0,
"type": "pointer",
},"1:1:AT_Translated_Set_2_keyboard": {
"is_virtual": 0,
"type": "keyboard",
},"0:0:sof-hda-dsp_Headphone": {
"is_virtual": 0,
"type": "keyboard",
},"1739:52619:SYNA8004:00_06CB:CD8B_Touchpad": {
"is_virtual": 0,
"type": "pointer",
},"1739:52619:SYNA8004:00_06CB:CD8B_Mouse": {
"is_virtual": 0,
"type": "pointer",
},"0:3:Sleep_Button": {
"is_virtual": 0,
"type": "keyboard",
},"0:5:Lid_Switch": {
"is_virtual": 0,
"type": "switch",
},"0:6:Video_Bus": {
"is_virtual": 0,
"type": "keyboard",
},"0:1:Power_Button": {
"is_virtual": 0,
"type": "keyboard",
}}
,"cursor_coords":{"x":972.821761,"y":670.836215}
}
fr fr that's a lot of JSON. dump is not playing around π«Ά
π― focus_tile
- Triggered by: the
focuscommand β¨ - JSON bits:
event_name:"focus_tile"old_tile_id: old tile id, as an integernew_tile_id: new tile id, as an integerworkspace: workspace number, as an integeroutput: name of the output, as a stringoutput_id: id of the output, as an integer
focus
cg-ipc{"event_name":"focus_tile",
"old_tile_id":14,
"new_tile_id":13,
"workspace":1,
"output":"eDP-1",
"output_id":1}
π₯οΈ fullscreen
- Triggered by: the
onlycommand, and that's it π - JSON bits:
event_name:"fullscreen"tile_id: tile id, as an integerworkspace: workspace number, as an integeroutput: output, as a stringoutput_id: id of the output, as an integer
only
cg-ipc{"event_name":"fullscreen",
"tile_id":3,
"workspace":1,
"output":"eDP-1",
"output_id":1}
π move_view_to_cycle_output
- Triggered by:
movetonextscreenand the similar commands π - JSON bits:
event_name:"move_view_to_cycle_output"view_id: view id, as an integerview_pid: pid of the processold_output: name of the old output, as a stringold_output_id: old output id, as an integerold_output_id: old output id, as an integer
bestie yes it lists old_output_id twice. that's literally what the page says, I'm not fixing it, I'm just the messenger π
movetonextscreen
cg-ipc{"event_name":"cycle_outputs",
"old_output":"eDP-1",
"new_output":"HDMI-A-1",
"reverse":0}
cg-ipc{"event_name":"move_view_to_cycle_output",
"view_id":11,
"view_pid":43123,
"old_output":"eDP-1",
"old_output_id":1,
"new_output":"HDMI-A-1",
"new_output_id":2}
π¦ move_view_to_output
- Triggered by: the
movetoscreencommand π« - JSON bits:
event_name:"move_view_to_output"view_id: view id, as an integerold_output: old output name, as a stringnew_output: new output name, as a string
movetoscreen 2
cg-ipc{"event_name":"switch_output",
"old_output":"eDP-1",
"new_output":"HDMI-A-1"}
cg-ipc{"event_name":"move_view_to_output",
"view_id":78,
"old_output":"eDP-1",
"new_output":"HDMI-A-1"}
π move_view_to_ws
- Triggered by: the
movetoworkspacecommand π¦ - JSON bits:
event_name:"move_view_to_ws"view_id: view id, as an integerold_workspace: old workspace number, as an integernew_workspace: new workspace number, as an integeroutput: name of the output, as a stringoutput_id: id of the output, as an integerview_pid: pid of the process
movetoworkspace 1
cg-ipc{"event_name":"switch_ws",
"old_workspace":1,
"new_workspace":1,
"output":"eDP-1"}
cg-ipc{"event_name":"move_view_to_ws",
"view_id":43,
"old_workspace":0,
"new_workspace":0,
"output":"eDP-1",
"output_id":1,
"view_pid":64908}
π new_output
- Triggered by: a new output being physically attached, like when you actually plug the cable in π§
- JSON bits:
event_name:"new_output"output: new output name, as a stringoutput_id: id of the new output, as an integerpriority: priority as peroutput prio <n>incagebreak-config(5)or default
# a new output is attached
cg-ipc{"event_name":"new_output","output":"HDMI-A-1","output_id":2,"priority":-1}
π resize_tile
- Triggered by: the whole
resizefamily of commands πΈ - JSON bits:
event_name:"resize_tile"tile_id: tile id, as an integerold_dims: list of coordinates[x coordinate of lower left corner, y coordinate of lower left corner, x coordinate of upper right corner, y coordinate of upper right corner]new_dims: list of coordinate[x coordinate of lower left corner, y coordinate of lower left corner, x coordinate of upper right corner, y coordinate of upper right corner]workspace: workspace number, as an integeroutput: name of the output, as a stringoutput_id: id of the output, as an integer
resizeleft
cg-ipc{"event_name":"resize_tile",
"tile_id":14,
"old_dims":"[1280,0,1440,1280]",
"new_dims":"[1270,0,1440,1290]",
"workspace":1,"output":"eDP-1",
"output_id":1}
cg-ipc{"event_name":"resize_tile",
"tile_id":13,
"old_dims":"[0,0,1440,1280]",
"new_dims":"[0,0,1440,1270]",
"workspace":1,
"output":"eDP-1",
"output_id":1}
ποΈ set_nws
- Triggered by: the
workspacescommand β¨ - JSON bits:
event_name:"set_nws"old_nws: old number of workspaces, as an integernew_nws: new number of workspaces, as an integer
workspaces 2
cg-ipc{"event_name":"set_nws","old_nws":1,"new_nws":2}
βοΈ split
- Triggered by: the
splitcommand π - JSON bits:
event_name:"split"tile_id: old tile id, as an integernew_tile_id: new tile id, as an integerworkspace: workspace number, as an integeroutput: output, as a stringoutput_id: id of the output, as an integervertical:0if horizontal split,1if not
hsplit
cg-ipc{"event_name":"split",
"tile_id":11,
"new_tile_id":12,
"workspace":1,
"output":"eDP-1",
"output_id":1,
"vertical":0}
π swap_tile
- Triggered by: the
exchangefamily of commands π« - JSON bits:
event_name:"swap_tile"tile_id: previous tile id, as an integertile_pid: pid of previous tileswap_tile_id: swap tile id, as an integerswap_tile_pid: pid of swap tileworkspace: workspace number, as an integeroutput: name of the output, as a stringoutput_id: id of the output, as an integer
exchangeright
cg-ipc{"event_name":"swap_tile",
"tile_id":1,
"tile_pid":53478,
"swap_tile_id":3,
"swap_tile_pid":98234,
"workspace":1,
"output":"eDP-1"}
ποΈ switch_default_mode
- Triggered by: the
setmodecommand π - JSON bits:
event_name:"switch_default_mode"old_mode: old mode namemode: new mode name
setmode top
cg-ipc{"event_name":"switch_default_mode","old_mode":"top","mode":"root"}
π₯οΈβ¨ switch_output
- Triggered by: the
screencommand - JSON bits:
event_name:"switch_output"old_output: name of the old output, as a stringold_output_id: old output id, as an integernew_output: name of the new output, as a stringnew_output_id: new output id, as an integer
screen 2
cg-ipc{"event_name":"switch_output",
"old_output":"eDP-1",
"old_output_id":1,
"new_output":"HDMI-A-1",
"new_output_id":2}
π switch_ws
- Triggered by: the
workspacecommand π¦ - JSON bits:
event_name:"switch_ws"old_workspace: old workspace number, as an integernew_workspace: new workspace number, as an integeroutput: name of the output, as a stringoutput_id: id of the output, as an integer
workspace 2
cg-ipc{"event_name":"switch_ws",
"old_workspace":1,
"new_workspace":2,
"output":"eDP-1",
"output_id":1}
view_map π±
- Trigger β a view gets opened by a process β¨
- JSON
event_name:"view_map"view_id: view id as an integertile_id: tile id as an integerworkspace: workspace number as an integeroutput: name of the output as a stringoutput_id: id of the output as an integerview_pid: pid of the process
# process opens a view
cg-ipc{"event_name":"view_map",
"view_id":28,
"tile_id":14,
"workspace":1,
"output":"eDP-1",
"output_id":1,
"view_pid":39827}
view_unmap π
- Trigger β a view gets closed by a process π
- JSON
event_name:"view_unmap"view_id: view id as an integertile_id: tile id as an integerworkspace: workspace number as an integeroutput: name of the output as a stringoutput_id: id of the output as an integerview_pid: pid of the process
# view is closed by the process
cg-ipc{"event_name":"view_unmap",
"view_id":24,
"tile_id":13,
"workspace":1,
"output":"eDP-1",
"output_id":1,
"view_pid":39544}
π SECURITY π
Okay bestie, listen, this part is important. The socket is not just vibing out there by default β you have to explicitly enable it with the -e flag. No flag, no socket. Periodt. π
The socket is locked down to you, the user, for reading, writing and execution β perms 700, so it's giving exclusive access only, nobody else gets in. π
β οΈ And here's the serious bit, no cap: all user software can execute arbitrary code while the cagebreak socket is running. Like, literally every program on your machine. So keep that in mind before you flip -e on, okay? π«Ά
π§ͺ EXAMPLES π§ͺ
Wanna poke at the socket from your terminal? Here's how, iconically simple:
nc -U $CAGEBREAK_SOCKET
Or if you're an ncat girlie:
ncat -U $CAGEBREAK_SOCKET
π SEE ALSO π
cagebreak(1) cagebreak-config(5)
Go read those too fr fr, they're lowkey essential. π
π BUGS π
Found something cursed? Check the GitHub Issues first: <https://github.com/project-repo/cagebreak/issues>
Prefer email? Mail contact: cagebreak @ project-repo . co
GPG Fingerprints (for the security-conscious besties π):
0A268C188D7949FEB39FD1462F2AD980247E4918283D10F54201B0C6CCEE2C561DE04E4B056C749D
π LICENSE π
Copyright (c) 2022 - 2024 The Cagebreak authors
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
That's the whole page, bestie β you made it to the end! π This lil masterpiece is Version 3.2.0, dated 2026-04-15, and it's the cagebreak-socket(7) page. Go forth and socket responsibly πβ¨
π¦ where this page comes from
- alpine 3.24: cagebreak-doc 3.2.0-r0 Β· MIT
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms